在Matlab中向量化条件求和循环

时间:2014-07-29 14:17:57

标签: matlab matrix sum conditional vectorization

我有两个M×N矩阵,标记为A和B,我想创建一个向量,包含B中每个唯一值A的所有项的总和。例如,我有以下矩阵:

A = [6 2 3 4
     5 2 3 3
     5 5 6 2];

B = [.2 .5 .4 .1
     .7 .2 .5 .1
     .6 .6 .1 .9];

我想创建一个向量C,其中每个索引对应于D = unique(A)的索引。因此,对于这种情况,D = [2,3,4,5,6]

for I = 1:length(D)
    C(I) = sum(B(A(:)==D(I));
end

当D为2000个项目且A和B都为~4000x20矩阵时,这变得非常慢。有关加快速度的任何帮助吗?我尝试了以下操作:

Indxs = bsxfun(@eq,A,reshape(D,1,1,length(D)));
for I = 1:size(Indxs,3)
    C(I) = sum(B(Indxs(:,:,I));
end

但实际上并不快。

1 个答案:

答案 0 :(得分:4)

您可以使用uniqueaccumarray的通常组合:

[D, ~, uA] = unique(A(:));
C = accumarray(uA, B(:));

使用您的示例数据,结果是:

>> D
D =
     2
     3
     4
     5
     6

>> C
C =
    1.6000
    1.0000
    0.1000
    1.9000
    0.3000

accumarray以其最基本的形式(两个输入参数)执行的操作是对具有相同第一个参数值的所有第二个参数值求和。


如果A仅包含正整数,则会出现sparsefind的单行解决方案:

[D, ~, C] = find(sparse(A(:), 1, B(:)));

这是有效的,因为sparse累积了对应于同一索引的值。