八度:求和索引元素
Octave: summing indexed elements
描述这一点的最简单方法是通过示例:
data = [1, 5, 3, 6, 10];
indices = [1, 2, 2, 2, 4];
result = zeroes(1, 5);
我希望result(1)
是索引为1
的data
中所有元素的总和,result(2)
是[中所有元素的总和=14=] 其索引为 2
,等等
这有效,但在应用于 64K 元素向量时(将 5
更改为 65535
)真的很慢:
result = result + arrayfun(@(x) sum(data(index==x)), 1:5);
我认为它正在创建具有 64K 元素的 64K 向量,这占用了时间。有没有更快的方法来做到这一点?还是我需要想出一个完全不同的方法?
for i = [1:5]
idx = indices(i);
result(idx) = result(idx) + data(i);
endfor
但这是一种非常非八度的方式。
鉴于 MATLAB 与 Octave 非常相似,我将提供一个在 MATLAB R2016b 上测试过的答案。查看 documentation of Octave 4.2.1 语法应该相同。
您需要做的就是:
result = accumarray(indices(:), data(:), [5 1]).'
给出:
result =
1 14 0 10 0
由于 accumarray
的预期输入,有必要重塑为列向量 (arrayName(:)
)。将大小指定为 [5 1]
然后转置结果以避免一些 MATLAB 错误。
accumarray
在MATLAB documentation
中也有深入介绍
描述这一点的最简单方法是通过示例:
data = [1, 5, 3, 6, 10];
indices = [1, 2, 2, 2, 4];
result = zeroes(1, 5);
我希望result(1)
是索引为1
的data
中所有元素的总和,result(2)
是[中所有元素的总和=14=] 其索引为 2
,等等
这有效,但在应用于 64K 元素向量时(将 5
更改为 65535
)真的很慢:
result = result + arrayfun(@(x) sum(data(index==x)), 1:5);
我认为它正在创建具有 64K 元素的 64K 向量,这占用了时间。有没有更快的方法来做到这一点?还是我需要想出一个完全不同的方法?
for i = [1:5]
idx = indices(i);
result(idx) = result(idx) + data(i);
endfor
但这是一种非常非八度的方式。
鉴于 MATLAB 与 Octave 非常相似,我将提供一个在 MATLAB R2016b 上测试过的答案。查看 documentation of Octave 4.2.1 语法应该相同。
您需要做的就是:
result = accumarray(indices(:), data(:), [5 1]).'
给出:
result =
1 14 0 10 0
由于 accumarray
的预期输入,有必要重塑为列向量 (arrayName(:)
)。将大小指定为 [5 1]
然后转置结果以避免一些 MATLAB 错误。
accumarray
在MATLAB documentation