【问题标题】:Vectorizing conditional summing loop in Matlab在 Matlab 中向量化条件求和循环
【发布时间】:2014-07-29 14:17:57
【问题描述】:

我有两个 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

但它并没有真正更快。

【问题讨论】:

  • 另外,我正在预分配 C 以加快速度。

标签: matlab matrix sum conditional vectorization


【解决方案1】:

您可以使用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 会累积对应于同一索引的值。

【讨论】:

  • +1 你能解释一下 accumarray 的作用比 MatLab 帮助文件更清楚吗?
  • 这要快得多!我不知道 accumarray,谢谢!
  • @EJG89 我已经添加了解释。我还包括使用sparse 的第二个解决方案
猜你喜欢
  • 2015-07-06
  • 2013-02-18
  • 1970-01-01
  • 2023-03-22
  • 2014-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多