How to cumulatively add consecutive ones between zeros in a logical vector

3 Ansichten (letzte 30 Tage)
I have a vector that looks like
x = [0 0 1 1 0 0 1 1 1 0 0 1]
and am trying to obtain
y = [0 0 1 2 0 0 1 2 3 0 0 1]
without using a loop. Any help would be much appreciated. The answer by Roger Stafford in https://www.mathworks.com/matlabcentral/answers/118828-how-to-count-the-number-of-consecutive-numbers-of-the-same-value-in-an-array is along the lines of what I am trying to achieve, but I am currently unable to manipulate his code to serve my purpose.

Akzeptierte Antwort

Andrei Bobrov
Andrei Bobrov am 26 Okt. 2017
y = x(:)';
ii = accumarray(bwlabel(y(:))+1,1);
y = [y,0];
y(strfind(y,[1 0])+1) = -ii(2:end);
out = cumsum(y(1:end-1));
  4 Kommentare
Shawn
Shawn am 26 Okt. 2017
Thank you very much! This is excellent.
Shawn
Shawn am 27 Okt. 2017
I added comments to the code in case anyone else is trying to understand it since it took me quite some time to understand the logic.
%%Cumulatively Add Consecutive Ones Between Zeros in a Logical Vector
x = [1 1 0 0 0 0 0 1 1 1 1 0 1 1 0 1 1 0 1 1 1 0 1 0 1 0 1 0 0 1 1 1];
%diff([0;x(:)]) vertically concatenates, adds a leading 0, and then
%takes the difference between consecutive points
%cumsum(diff([0;x(:)]) == 1) finds the location of each change from 0 to 1,
%keeps that value constant elementwise until another 0 to 1 shows up, and
%then increments by 1 each time it shows up
%cumsum(diff([0;x(:)]) == 1).*x(:) elementwise multiplies the previous
%equation by the original vector, which will set corresponding 0 elements
%to 0
%accumarray(cumsum(diff([0;x(:)]) == 1).*x(:)+1,1) adds one to the previous
%equation and then creates histogram style binning of the appearance of
%each number from 1 on (since 1 was added, the index corresponds to one
%more than the actual number)
ii = accumarray(cumsum(diff([0;x(:)]) == 1).*x(:)+1,1);
%adds a trailing 0 to the original vector
y = [x,0];
%strfind(y,[1 0])+1 finds the locations of every instance of a 1 then a 0
%showing up and then adds 1 to get the indeces of that 0
%y(strfind(y,[1 0])+1) = -ii(2:end) replaces the previously described 0
%indeces with the negative of the corresponding bin number of how many
%times in a row the number 1 was repeated prior to it (recall that the
%index is one greater than the actual number and that we counted up from 1
%every time that a 0 to 1 showed up)
y(strfind(y,[1 0])+1) = -ii(2:end);
%now we cumulatively add each number together, so whenever we have ones
%they will add and then thanks to the last step, the 0 following a 1
%contains the negative of the number of ones that preceeded it, so it will
%reset the count to 0
out = cumsum(y(1:end-1));

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by