问题
For example, if
A = [7,8,1,1,2,2,2]; % the bins (or subscripts)
B = [2,1,1,1,1,1,2]; % the array
then the desired function "binsum" has two outputs, one is the bins, and the other is the sum. It is just adding values in B according to subscripts in A. For example, for 2, the sum is 1 + 1 + 2 = 4, for 1 it is 1 + 1 = 2.
[bins, sums] = binsum(A,B);
bins = [1,2,7,8]
sums = [2,4,2,1]
The elements in "bins" need not be ordered but must correspond to elements in "sums". This can surely be done by "for" iterations, but "for" iteration is not desired, because there is a performance concern. It is best if there is a build in function for this.
Thanks a lot!
回答1:
This is another job for accumarray
A = [7,8,1,1,2,2,2]; % the bins (or subscripts)
B = [2,1,1,1,1,1,2]; % the array
sums = accumarray(A.', B.').';
bins = unique(A);
Results:
>> bins
bins =
1 2 7 8
sums =
2 4 0 0 0 0 2 1
The index in sums
corresponds to the bin value, so sums(2) = 4
. You can use nonzeros
to remove the unused bins so that bins(n)
corresponds to sums(n)
sums = nonzeros(sums).';
sums =
2 4 2 1
or, to generate this form of sums
in one line:
sums = nonzeros(accumarray(A.', B.')).';
回答2:
Another possibility is to use sparse and then find.
Assuming
A
contains positive integers,[bins, ~, sums] = find(sparse(A, 1, B));
This works because
sparse
automatically adds values (third input) for matching positions (as defined by the first two inputs).If
A
can contain arbitrary values, you also need a call to unique, andfind
can be replaced by nonzeros:[bins, ~, labels]= unique(A); sums = nonzeros(sparse(labels, 1, B));
回答3:
Here is a solution using sort
and cumsum
:
[s,I]=sort(A);
c=cumsum(B(I));
k= [s(1:end-1)~=s(2:end) true];
sums = diff([0 c(k)])
bins = s(k)
来源:https://stackoverflow.com/questions/45661195/any-way-for-matlab-to-sum-an-array-according-to-specified-bins-not-by-for-iterat