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

3 次查看(过去 30 天)
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.

采纳的回答

Andrei Bobrov
Andrei Bobrov 2017-10-26
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 个评论
Shawn
Shawn 2017-10-27
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));

请先登录,再进行评论。

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Logical 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by