How to get cumsum to work on consecutive values and restart if there is a 0 value?

14 views (last 30 days)
Good Afternoon,
Say I had a a vector
G = [ 0 0 1 1 1 0 0 0 0 1 1 1 1 1 1 1 0 NaN 0 NaN 0 0 0 0]
and I wanted to get a vector
H = [0 0 1 2 3 0 0 0 0 1 2 3 4 5 6 7 0 NaN 0 NaN 0 0 0 0 ]
from this. Is there an easy way to go about this? I essentially just want to restart cumsum everytime there is a break in the sequence.
Thank you for any help/advice/time you can offer!

Answers (2)

Jos (10584)
Jos (10584) on 15 Feb 2018
Here is a rather easy approach:
G = [ 0 0 1 1 1 0 0 0 0 1 1 1 1 1 1 1 0 NaN 0 NaN 0 9 9 9 9] % data
ix = cumsum([true diff(G)~=0]) % index the sections
tmp = arrayfun(@(k) cumsum(G(ix==k)), 1:ix(end), 'un', 0) % cumsum each section
H = cat(2,tmp{:}) % concatenate the cells

Guillaume
Guillaume on 15 Feb 2018
There is no built-in function for this. I think there may be one on the FileExchange, otherwise, you'll have to write your own. A loop is probably the easiest and fastest:
H = zeros(size(G));
count = 0;
for idx = 1:numel(G)
if G(idx)
count = count + 1;
else
count = 0;
end
H(idx) = count;
end
  2 Comments
Birdman
Birdman on 15 Feb 2018
Edited: Birdman on 15 Feb 2018
What if there are 10000 elements in G? Would for loop be faster then?
Guillaume
Guillaume on 15 Feb 2018
Probably not faster than a mex. But most likely faster than anything else. That's a very simple loop so the jit compiler should optime that result (as long as it's in a function)

Sign in to comment.

Tags

Community Treasure Hunt

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

Start Hunting!