4

我有一个包含百分比值的矩阵,其中每一行代表一个单独的观察值。我需要计算这些值对应于相同下标的累积乘积。我尝试使用该accumarray函数,只要我使用列向量作为值(而不是矩阵),它就可以正常工作并且符合预期。我想知道在不遍历值矩阵的各个列的情况下解决问题的最佳方法是什么?

这是我的示例代码:

subs = [1;1;1;2;2;2;2;2;3;3;4;4;4];
vals1 = [0.1;0.05;0.2;0.02;0.09;0.3;0.01;0.21;0.12;0.06;0.08;0.12;0.05];

% This is working as expected
result1 = accumarray(subs,vals1, [], @(x) prod(1+x) -1)


vals2 = [vals1,vals1];

% This is not working as the second input parameter of accumarray
% apperently must be a vector (rather than a matrix)
result2 = accumarray(subs, vals2, [], @(x) prod(1+x) -1)
4

2 回答 2

2

对于 vals,您可以将其设置为1:size(vals2,1)并使用它来提取vals2. 该函数还需要返回单元格。

result2 = accumarray(subs, 1:size(vals2,1), [], @(x) {prod(1+vals2(x,:),1)-1})

您可以连接单元格元素:

result3 = vertcat(result2{:})

或全部在一行中:

result3 = cell2mat( accumarray(subs, 1:size(vals2,1), [], @(x) {prod(1+vals2(x,:),1)-1}))

result3 =

   0.38600   0.38600
   0.76635   0.76635
   0.18720   0.18720
   0.27008   0.27008

[10000 x 200]Octave 中的测试结果比较了使用矩阵作为输入的三种建议方法:

subs = randi(1000,10000,1);
vals2 = rand(10000,200);

=========CELL2MAT========
Elapsed time is 0.130961 seconds.
=========NDGRID========
Elapsed time is 3.96383 seconds.
=========FOR LOOP========
Elapsed time is 6.16265 seconds.

在线演示

于 2017-11-29T11:31:35.440 回答
0

您需要添加第二组下标subs(使其为 N×2)来处理您的 2D 数据,该数据仍必须作为 N 元素向量传递(即 中的每一行一个元素subs)。您可以使用以下命令生成一组新的 2D 下标ndgrid

[subs1, subs2] = ndgrid(subs, 1:size(vals2, 2));
result2 = accumarray([subs1(:) subs2(:)], vals2(:), [], @(x) prod(1+x) -1)

以及您的样本数据的结果:

result2 =

    0.3860    0.3860
    0.7664    0.7664
    0.1872    0.1872
    0.2701    0.2701
于 2017-11-29T16:09:21.747 回答