问题
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
Acontains positive integers,[bins, ~, sums] = find(sparse(A, 1, B));This works because
sparseautomatically adds values (third input) for matching positions (as defined by the first two inputs).If
Acan contain arbitrary values, you also need a call to unique, andfindcan 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