我试图通过摆脱一些for循环来优化代码的运行时间。但是,我有一个变量,该变量在每次迭代中都会增加,有时会重复索引。我在这里提供一个最小的示例:
a = [1 4 2 2 1 3 4 2 3 1]
b = [0.5 0.2 0.3 0.4 0.1 0.05 0.7 0.3 0.55 0.8]
c = [3 5 7 9]
for i = 1:10
c(a(i)) = c(a(i)) + b(i)
end
理想情况下,我想通过以下方式进行计算:
c(a) = c(a) + b
,但是显然它不会给我相同的结果,因为我不得不多次重新计算同一索引的值,所以这种将其向量化的方法将行不通。 另外,如果这很重要,我会在Matlab或Octave中工作。
非常感谢您的帮助,我不确定是否可以进行矢量化。
编辑:非常感谢您到目前为止的回答。我发现了accumarray,这是我以前不知道的,并且也理解为什么更改Matlab和Octave之间的for循环会给我这么不同的时间。我也更了解我的问题。我给出了一个太简单的示例,以为可以扩展,但是如果b是矩阵呢?
(此刻让我们忘记c):
a = [1 4 2 2 1 3 4 2 3 1]
b =[0.69 -0.41 -0.13 -0.13 -0.42 -0.14 -0.23 -0.17 0.22 -0.24;
0.34 -0.39 -0.36 0.68 -0.66 -0.19 -0.58 0.78 -0.23 0.25;
-0.68 -0.54 0.76 -0.58 0.24 -0.23 -0.44 0.09 0.69 -0.41;
0.11 -0.14 0.32 0.65 0.26 0.82 0.32 0.29 -0.21 -0.13;
-0.94 -0.15 -0.41 -0.56 0.15 0.09 0.38 0.58 0.72 0.45;
0.22 -0.59 -0.11 -0.17 0.52 0.13 -0.51 0.28 0.15 0.19;
0.18 -0.15 0.38 -0.29 -0.87 0.14 -0.13 0.23 -0.92 -0.21;
0.79 -0.35 0.45 -0.28 -0.13 0.95 -0.45 0.35 -0.25 -0.61;
-0.42 0.76 0.15 0.99 -0.84 -0.03 0.27 0.09 0.57 0.64;
0.59 0.82 -0.39 0.13 -0.15 -0.71 -0.84 -0.43 0.93 -0.74]
我现在了解到,我要做的是每个组的rowSum,考虑到我使用的是Octave,我不能使用“ splitapply”。我试图归纳您的答案,但是accumarray无法用于矩阵,而且我也无法归纳@ rahnema1解决方案。所需的输出将是:
[0.34 0.26 -0.93 -0.56 -0.42 -0.76 -0.69 -0.02 1.87 -0.53;
0.22 -1.03 1.53 -0.21 0.37 1.54 -0.57 0.73 0.23 -1.15;
-0.20 0.17 0.04 0.82 -0.32 0.10 -0.24 0.37 0.72 0.83;
0.52 -0.54 0.02 0.39 -1.53 -0.05 -0.71 1.01 -1.15 0.04]
“等同于”
[sum(b([1 5 10],:))
sum(b([3 4 8],:))
sum(b([6 9],:))
sum(b([2 7],:))]
非常感谢,如果您认为我应该将此问题包含在另一个问题中,而不是添加编辑,那么我会这样做。
答案 0 :(得分:6)
可以通过accumarray
完成:
a = [1 4 2 2 1 3 4 2 3 1];
b = [0.5 0.2 0.3 0.4 0.1 0.05 0.7 0.3 0.55 0.8];
c = [3 5 7 9];
c(:) = c(:) + accumarray(a(:), b(:));
这将b
定义的组中的a
中的值相加,并将其添加到原始c
中。
如果b
是矩阵,则可以使用
full(sparse(repmat(a, 1, size(b,1)), repelem(1:size(b,2), size(b,1)), b))
或
accumarray([repmat(a, 1, size(b,1)).' repelem(1:size(b,2), size(b,1)).'], b(:))
答案 1 :(得分:4)
矩阵乘法和隐式展开,可以使用(八度):
nc = numel(c);
c += b * (1:nc == a.');
对于大尺寸输入,使用稀疏矩阵可能会提高存储效率:
nc = numel(c);
nb = numel(b);
c += b * sparse(1:nb, a, 1, nb, nc);
Edit
:如果b
是矩阵,则可以将此解决方案扩展为:
nc = numel(c);
na = numel(a);
out = sparse(a, 1:na, 1, nc, na) * b;