向量化属于一个组的求和值

Vectorize summing values that belong to a group

是否可以对经过不同索引映射的循环进行矢量化?例如:

a = zeros(1, 5);
m = [4 3 5; 5 1 3];
f = [1 2 3; 4 5 6];

for ii = 1:size(m,1)
    a(m(ii,:)) = a(m(ii,:)) + f(ii,:);
end

给出输出:

a = [5 0 2+6 1 3+4] = [5 0 8 1 7]

这可以不用 for 循环来完成吗?

这是accumarray的经典案例。 accumarray 通过提供一组键和一组与每个键关联的值来工作。 accumarray 将属于同一键的所有值分组,并对所有值执行某些操作。默认行为是将属于同一键的所有值加在一起,这就是您所追求的。

在您的例子中,m 是键,f 是您要添加的属于同一键的值。因此:

>> a = accumarray(m(:), f(:))

a =

     5
     0
     8
     1
     7

一般来说,您可能丢失了钥匙。因此,您可以选择指定输出数组的输出维度,它应该是 m:

中看到的 maximum 键值
a = accumarray(m(:), f(:), [max(f(:)), 1]);

这当然是假设 f 完全由正值组成。

一般来说,如果您在 f 中有浮点数,那么开箱即用的 accumarray 将不起作用,因为键被假定为严格的正整数。然而,一个常见的技巧是为 f 的每个值分配一个唯一的 ID,并将其用作 accumarray 的输入。 unique 的第三个输出应该为你做这个。您还需要 unique 的第一个输出来帮助您找出哪个总和属于哪个键:

[msorted,~,id] = unique(m);
a = accumarray(id, f(:));
out = [msorted a];

out 将包含一个 2 列矩阵,其中每一行在 m 中为您提供一个唯一值,以及在 m 中共享相同键的所有值的相关总和。 =31=]