expanded accumarray output for unsorted data in matlab

128 views Asked by At

I am using the accumarray function to sum the values in vector "data" within categories defined by the vector "id". I want my vector id to not be necessarily sorted, and also potentially containing non-consecutive numbers. I also want to end up with a vector of sums Sij that is the same size of id (rather than the same size of unique(id)).

For instance

id = [3 2 4 3 2 3]';
data = [6 43 3 4 2 5]';

As an output I want

Sij = [15 45 3 15 45 15]';

I managed to do it by creating datasets and use the join function (using the following code), but I was wondering if there's a more efficient way (this is part of a likelihood function I am maximizing and I'd like to speed it up). Thanks!

clear;
id = [3 2 4 3 2 3]';
data = [6 43 3 4 2 5]';
indices = [id ones(size(id))];
S = accumarray(indices, data);
DS  = dataset((1:size(S))',S);
DS = DS(DS.S~=0,:);
DS.Properties.VarNames={'id','S'};
C =join(dataset(id),DS);
Sij = C.S;
1

There are 1 answers

1
Luis Mendo On BEST ANSWER

You basically need to replicate the output of accumarray. The replication pattern is given by the third output of unique:

[~, ~, k] = unique(id);
s = accumarray(k,data);
result = s(k);

Another possibility: use bsxfun to detect equal values of id, and then matrix multiplication to accumulate the corresponding values of data:

result = bsxfun(@eq, id, id.') * data;

Test to see which approach is fastest for you.