# sum of two different data series

2 views (last 30 days)
Commented: Hamad on 6 Aug 2014
Hey all. I would like some help please on finding an efficient way of doing this:
I have two data series combined into one vector, so something like the below example
data =
DataPoint DataIdx
0.50 1
0.25 1
0.80 2
0.10 1
0.60 1
0.50 2
0.25 2
0.50 2
0.40 1
0.10 1
0.50 1
What I would like to do is add up all the data points per dataIdx, but preserve the order. So the output would be a "consolidated" vector which would look something like:
output =
DataConsolidated DataIdx
0.75 1
0.80 2
0.70 1
1.25 2
1.00 1
At the moment, I am using a for-loop that keeps a tally, but I hope there is a more elegant solution. I think this might lend itself well to an application of "accumarray", but I have not that much experience with this function. Any help pls?
Image Analyst on 6 Aug 2014
Maybe it's better, for code maintainability and ease of understanding it (especially later), if you just go with a simple intuitive for loop rather than some cryptic accumarray function that you don't understand. Simplicity has its benefits.

Azzi Abdelmalek on 6 Aug 2014
A=[0.50 1
0.25 1
0.80 2
0.10 1
0.60 1
0.50 2
0.25 2
0.50 2
0.40 1
0.10 1
0.50 1 ]
jj=[0; diff(A(:,2))~=0];
kk=cumsum(jj);
[~,id]=unique(kk);
out=[ accumarray(kk+1,A(:,1)) A(id,2)]
Efficient, concise, and informative. Thanks very much! Hamad.

Oleg Komarov on 6 Aug 2014
You cannot use DataIdx directly as subs in accumarray() because in your example each streak of indices is treated as a separate accumulation block while the labeling is repeated, i.e. the 1s appear again after 2. You need to re-label the DataIdx and accumulate.
% Run-length encode the DataIdx:
DataIdx = [1,1,2,1,1,2,2,2,1,1,1];
[val,len] = RunLength(DataIdx);
% Decode back, but with a progressive index, i.e. expand sequential positions by the len of each streak:
subs = RunLength(1:numel(val),len)'
% Accumulate
[val' accumarray(subs, DataPoint)]
PS. RunLength() is on the FEX by Jan Simon.