Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Finding and Replacing Consecutive Numbers in an Array

Subject: Finding and Replacing Consecutive Numbers in an Array

From: Ern

Date: 30 Mar, 2011 13:23:22

Message: 1 of 9

Hi,

I've got what I feel is quite a complex problem to solve. I have an array of values between 0 and 3, and I want to sequentially search that array to find runs of consecutive numbers. I then want to replace any runs which are less than 5 values long with the values from the previous run.

If for example I have an array X (in reality this would be upto 70,000 entries long):

X = [1 1 1 1 1 0 0 3 3 3 3 3 2 2 2 1 1]

I want the code to detect that there is a run of two zeros following a run of five 1s. The code would then replace the two zeros with 1s. It would then see that there are five 3's followed by three 2s, so the 2s would be replaced by 3s. Following that are two 1s, which in turn would be replaced by 3s.

All I've found so far are ways to count the numbers of runs in an array, and how to replace ALL the elements of a certain value, but I can't see how that would help with this situation. I've put the two snippets of code below:

Using this to find consecutive numbers http://www.mathworks.com/matlabcentral/fileexchange/6436
% the data
     v=[1 2 4 4 3 3 3 2 1 1 1 1 4 2 2 2 2 2];
     n=4;
% the engine
     [len,val]=rude(v);
     ix=len>=n;
     vn=rude(len(ix),val(ix));
% the result
     disp(vn);


Replace numbers:
% Replace all zeros with 1s
 index = find(X == 0 );
 X(index) = [1]

Regards,

Ern

Subject: Finding and Replacing Consecutive Numbers in an Array

From: Roger Stafford

Date: 31 Mar, 2011 19:24:20

Message: 2 of 9

"Ern" wrote in message <imvasa$gbb$1@fred.mathworks.com>...
> I've got what I feel is quite a complex problem to solve. I have an array of values between 0 and 3, and I want to sequentially search that array to find runs of consecutive numbers. I then want to replace any runs which are less than 5 values long with the values from the previous run.
> .......
- - - - - - - - - - -
  You can use a for-loop. If X is a row vector, do this:

 f = find([true,diff(X)~=0,true]);
 for k = length(f)-1:-1:2
  if f(k+1)-f(k) < 5
   X(f(k):f(k+1)-1) = X(f(k)-1);
  end
 end

  Solutions that avoid for-loops tend to be awkward and inefficient.

Roger Stafford

Subject: Finding and Replacing Consecutive Numbers in an Array

From: Florin Neacsu

Date: 31 Mar, 2011 21:38:04

Message: 3 of 9

"Roger Stafford" wrote in message <in2kd4$jak$1@fred.mathworks.com>...
> "Ern" wrote in message <imvasa$gbb$1@fred.mathworks.com>...
> > I've got what I feel is quite a complex problem to solve. I have an array of values between 0 and 3, and I want to sequentially search that array to find runs of consecutive numbers. I then want to replace any runs which are less than 5 values long with the values from the previous run.
> > .......
> - - - - - - - - - - -
> You can use a for-loop. If X is a row vector, do this:
>
> f = find([true,diff(X)~=0,true]);
> for k = length(f)-1:-1:2
> if f(k+1)-f(k) < 5
> X(f(k):f(k+1)-1) = X(f(k)-1);
> end
> end
>
> Solutions that avoid for-loops tend to be awkward and inefficient.
>
> Roger Stafford


Dear Roger,

What if X = [1 1 1 1 1 3 3 3 3 3 3 3 0 0 2 2 2] ? The code you suggest yields

X = 1 1 1 1 1 3 3 3 3 3 3 3 3 3 0 0 0

Is that what OP wants ? I understand that runs of consecutive numbers should be changed (with the condition of length<5) but in this example there are not consecutive numbers, so nothing should be changer. Am I misunderstanding ?

Regards,
Florin

Subject: Finding and Replacing Consecutive Numbers in an Array

From: Roger Stafford

Date: 31 Mar, 2011 21:59:05

Message: 4 of 9

"Florin Neacsu" <fneacsu2@gmail.com> wrote in message <in2s7s$7af$1@fred.mathworks.com>...
> Dear Roger,
>
> What if X = [1 1 1 1 1 3 3 3 3 3 3 3 0 0 2 2 2] ? The code you suggest yields
>
> X = 1 1 1 1 1 3 3 3 3 3 3 3 3 3 0 0 0
>
> Is that what OP wants ? I understand that runs of consecutive numbers should be changed (with the condition of length<5) but in this example there are not consecutive numbers, so nothing should be changer. Am I misunderstanding ?
>
> Regards,
> Florin
- - - - - - - - -
  It is true that Ern said, "runs of consecutive numbers", but I assumed he really meant "consecutive sequences of equal numbers". His example with:

"X = [1 1 1 1 1 0 0 3 3 3 3 3 2 2 2 1 1]
I want the code to detect that there is a run of two zeros following a run of five 1s. The code would then replace the two zeros with 1s. It would then see that there are five 3's followed by three 2s, so the 2s would be replaced by 3s. Following that are two 1s, which in turn would be replaced by 3s."

appears to bear that out, except that I would expect the last two ones to be replaced by twos, not threes.

Roger Stafford

Subject: Finding and Replacing Consecutive Numbers in an Array

From: Florin Neacsu

Date: 31 Mar, 2011 22:12:02

Message: 5 of 9

"Roger Stafford" wrote in message <in2tf9$qc7$1@fred.mathworks.com>...
> "Florin Neacsu" <fneacsu2@gmail.com> wrote in message <in2s7s$7af$1@fred.mathworks.com>...
> > Dear Roger,
> >
> > What if X = [1 1 1 1 1 3 3 3 3 3 3 3 0 0 2 2 2] ? The code you suggest yields
> >
> > X = 1 1 1 1 1 3 3 3 3 3 3 3 3 3 0 0 0
> >
> > Is that what OP wants ? I understand that runs of consecutive numbers should be changed (with the condition of length<5) but in this example there are not consecutive numbers, so nothing should be changer. Am I misunderstanding ?
> >
> > Regards,
> > Florin
> - - - - - - - - -
> It is true that Ern said, "runs of consecutive numbers", but I assumed he really meant "consecutive sequences of equal numbers". His example with:
>
> "X = [1 1 1 1 1 0 0 3 3 3 3 3 2 2 2 1 1]
> I want the code to detect that there is a run of two zeros following a run of five 1s. The code would then replace the two zeros with 1s. It would then see that there are five 3's followed by three 2s, so the 2s would be replaced by 3s. Following that are two 1s, which in turn would be replaced by 3s."
>
> appears to bear that out, except that I would expect the last two ones to be replaced by twos, not threes.
>
> Roger Stafford

Hello,

I agree that the last substitution is ambigous. Maybe he/she will post an elucidator example.

Regards,
Florin

Subject: Finding and Replacing Consecutive Numbers in an Array

From: Bruno Luong

Date: 1 Apr, 2011 06:15:19

Message: 6 of 9

You might try this code using my SplitVec function on FEX:

% http://www.mathworks.com/matlabcentral/fileexchange/?term=SplitVec
X = [1 1 1 1 1 0 0 3 3 3 3 3 2 2 2 1 1]

[lgt v int] = SplitVec(X, [], 'length', 'firstelem', 'bracket'); % FEX
Y = zeros(size(X));
b = lgt >= 5;
Y(int(b,1)) = diff([0 v(b)]);
Y = cumsum(Y)

% Bruno

Subject: Finding and Replacing Consecutive Numbers in an Array

From: Bruno Luong

Date: 1 Apr, 2011 06:59:05

Message: 7 of 9

Sorry the correct URL for SplitVec is:
http://www.mathworks.com/matlabcentral/fileexchange/24255-consecutive-vector-spliter

% Bruno

Subject: Finding and Replacing Consecutive Numbers in an Array

From: Ern

Date: 1 Apr, 2011 07:12:05

Message: 8 of 9

"Bruno Luong" <b.luong@fogale.findmycountry> wrote in message <in3qhn$rv3$1@fred.mathworks.com>...
> You might try this code using my SplitVec function on FEX:
>
> % http://www.mathworks.com/matlabcentral/fileexchange/?term=SplitVec
> X = [1 1 1 1 1 0 0 3 3 3 3 3 2 2 2 1 1]
>
> [lgt v int] = SplitVec(X, [], 'length', 'firstelem', 'bracket'); % FEX
> Y = zeros(size(X));
> b = lgt >= 5;
> Y(int(b,1)) = diff([0 v(b)]);
> Y = cumsum(Y)
>
> % Bruno


Hi Bruno,

Thanks for that. I was intrigued by your SplitVec function yesterday but couldn't figure out what to do with it. That works great for the test matrix but I'm getting the following error when i try to apply it to my code:

Error using ==> horzcat
CAT arguments dimensions are not consistent.

Error in ==> gazeplot at 36
a(int(b,1)) = diff([0 v(b)]);


My code:
x=load('C:\Logs\Prepared Data\world_data.txt'); % Loads text log containing 3 columns

%The following section creates one array for each of the columns from the loaded log file
X=(x(:,1));
Y=x(:,2);
C=(x(:,3));

%Shift timing column (X) to give timing in seconds starting at 0secs
Xmax = max(X);
Xmin = min(X);
T = Xmax - Xmin;
Z = (X) - Xmin;


[r] = find(Y<1); % Find all zero elements in Y column
Y(r)= C(r); % Replace all zero elements with corresponding element from C column

[lgt v int] = SplitVec(Y, [], 'length', 'firstelem', 'bracket'); % FEX
a = zeros(size(Y));
b = lgt >= 5;
a(int(b,1)) = diff([0 v(b)]); %This is the line which is giving me the error.
a = cumsum(a)

Y=a;
A=Y;


I can't see what's causing the problem, it works fine for smaller arrays that I've tried, and I know that your SplitVec function works fine on this array as I tried it yesterday.

Regards,

Ern

Subject: Finding and Replacing Consecutive Numbers in an Array

From: Ern

Date: 1 Apr, 2011 07:55:04

Message: 9 of 9

It's fine now thanks. I made a simple mistake and needed to transform the array from a column vector to a row vector! Seems to work great now!

Thanks,

Ern

Tags for this Thread

No tags are associated with this thread.

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us