3 views (last 30 days)

Hello,

I have a data set vector that I've reduced down to 0's, 1's, and 2's. What I want to do is replace any 2's with 0's if they are following a 0, up until the next 1 shows up. For example:

if the original vector: A = [0 0 0 2 2 2 1 2 1 2 2 0 0]

the new vector : B = [0 0 0 0 0 0 1 2 1 2 2 0 0]

My vectors will have about 25,000 to 500,000 data points. Any way that I've tried to do this ends up taking way too long. I'd be appreciative of any advice that you'd be willing to give. If it helps, 0's will never be followed directly by 1's, and any 2's following a 0 will always lead into a 1 before the next 0 shows up.

Daniel

Robert U
on 18 May 2020

Hi Daniel Steyer,

this code snippet should provide the requested functionality.

cIn = cellfun(@num2str,num2cell(A),'UniformOutput',false);

strIn = [cIn{:}];

indToChange = regexp(strIn,'(?<=0)(2)+(?=1)','tokenExtents');

for indChanges = 1:numel(indToChange)

dInput(indToChange{indChanges}(1):indToChange{indChanges}(2)) = 0;

end

B = dInput;

Kind regards,

Robert

Stephen Cobeldick
on 22 May 2020

Note that this

cIn = cellfun(@num2str,num2cell(A),'UniformOutput',false);

strIn = [cIn{:}];

should be replaced with this simpler and much more efficient code:

strIn = sprintf('%u',A);

Stephen Cobeldick
on 18 May 2020

Edited: Stephen Cobeldick
on 22 May 2020

This should be reasonably efficient:

A = [0,0,0,2,2,2,1,2,1,2,2,0,0];

D = diff(A);

B = find([0,D]==2);

E = find([D==-1,true] & A==2);

for k = 1:numel(B)

A(B(k):E(k)) = 0;

end

Giving:

A =

0 0 0 0 0 0 1 2 1 2 2 0 0

Note that this approach relies on your statement "...any 2's following a 0 will always lead into a 1..."

EDIT: more robust end detection:

A = [0,0,0,2,2,2,1,2,1,2,2,0,0,0,0,0,2,2,2,1,2,1,2,2,0,0];

D = diff(A);

B = find([false,D==2]);

E = find([D==-1,true]);

for k = 1:numel(B)

X = B(k):E(find(E>B(k),1));

A(X) = 0;

end

Stephen Cobeldick
on 21 May 2020

Yes you are right, detecting the end index was not very robust. I tried various methods, and this worked well:

A = [0,0,0,2,2,2,1,2,1,2,2,0,0,0,0,0,2,2,2,1,2,1,2,2,0,0];

D = diff(A);

B = find([false,D==2]);

E = find([D==-1,true]);

for k = 1:numel(B)

X = B(k):E(find(E>B(k),1));

A(X) = 0;

end

Giving:

A =

0 0 0 0 0 0 1 2 1 2 2 0 0 0 0 0 0 0 0 1 2 1 2 2 0 0

Opportunities for recent engineering grads.

Apply Today
## 0 Comments

Sign in to comment.