Asked by hdr mhr
on 1 May 2013

I have an array that has the following pattern, lets call it A

A=[NaN NaN...NaN 0 1.445 4.223 5.353 1.3534 NaN NaN...NaN 2.45 1.54 0.98 ....NaN....] What I want to do is to calculate the sum of each group of numbers that appear after the each group of NaNs, for example sum(0 1.445 4.223 5.353 1.3534) = B(1), sum(2.45 1.54 0.98)= B(2), and so on.

Can you please guide me through an efficient way to do this?

Answer by Cedric Wannaz
on 1 May 2013

Edited by Cedric Wannaz
on 1 May 2013

Accepted Answer

It is not trivial actually. Look at the following and let me know if there is anything unclear. Also, I let you check that it manages well limit cases, and update it otherwise.

isnanId = isnan(A) ; groupId = [1, isnanId(1:end-1)] ; groupId = cumsum(groupId(~isnanId)) ; A = A(~isnanId) ; B = accumarray(groupId(:), A(:)) ;

Running this code produces:

>> B B = 12.3744 4.9700

which is the group-sum that you are looking for.

Answer by Azzi Abdelmalek
on 1 May 2013

A=[NaN NaN NaN 1 2 3 NaN NaN NaN 4 5 6 10 NaN NaN 2 NaN NaN 1 2 0 4] idx=find(~isnan(A)) id=[1 diff(idx)] ii=[1 find(id>1)] for k=1:numel(ii)-1 s(k)=sum(A(idx(ii(k)):idx(ii(k+1)-1))) end s(k+1)=sum(A(idx(ii(k+1)):idx(end)))

hdr mhr
on 2 May 2013

Thank you for the answer. It works perfectly fine but I think the first algorithm works a bit faster when the array is large. For a 736*1 array, the first method took:

Elapsed time is 2.634142 seconds.

and your method:

Elapsed time is 2.979654 seconds.

Thank you very much

Log in to comment.

Opportunities for recent engineering grads.

Apply Today
## 0 Comments

Log in to comment.