计算 Octave 中行组的列的平均值
Posted
技术标签:
【中文标题】计算 Octave 中行组的列的平均值【英文标题】:Compute mean of columns for groups of rows in Octave 【发布时间】:2020-09-02 11:57:01 【问题描述】:我有一个矩阵,例如:
1 2
3 4
4 5
我还有一个对行进行分组的规则,它被定义为一个组 ID 的向量,如下所示:
1
2
1
这意味着第一行和第三行属于同一个组(ID 1),第二行属于另一个组(ID 2)。所以,我想计算每个组的平均值。这是我的示例的结果:
2.5 3.5
3 4
更正式地说,有一个大小为(m,n)的矩阵A,有若干组k 和一个大小为 (m, 1) 的向量 v,其值是从 1 到 k 的整数。结果是一个大小为 (k, n) 的矩阵 R,其中索引为 r 的每一行对应于r组的平均值。
这是我在 Octave 中使用 for-loop 的解决方案(可以满足我的需要):
R = zeros(k, n);
for r = 1:k
R(r, :) = mean(A((v == r), :), 1);
end
我想知道它是否可以矢量化。因此,我需要用矢量化解决方案替换 for 循环,这将比迭代解决方案更有效。
这是我以矢量化方式解决问题的众多尝试之一(但不起作用):
R = mean(A((v == 1:k), :);
【问题讨论】:
【参考方案1】:只要我们的数据是浮点数,你就可以自己手动求和然后除,使用accumdim
。像这样:
octave:1> A = [1 2; 3 4; 4 5];
octave:2> subs = [1; 2; 1];
octave:3> accumdim (subs, A) ./ accumdim (subs, ones (rows (subs), 1))
ans =
2.5000 3.5000
3.0000 4.0000
【讨论】:
我不知道 accumdim。这似乎是我正在寻找的功能。谢谢你的指点。 不知道比this回答效率高吗?老实说,使用 accumdim 的解决方案可读性较差,所以我更喜欢它的唯一原因是效率。 @IhorDobrovolskyi 其他原因是 1) 更少的内存使用和 2) 适用于旧版本的 Octave(我发现这在 HPC 中很常见)。此外,accumdim
和 accumarray
(accumdim
的更复杂但更灵活的版本)是(曾经)这类问题的典型答案,对我来说似乎很容易阅读。我想可读性是相对的,可能取决于您对这些功能与自动广播的使用程度。【参考方案2】:
您可以将其视为矩阵乘法问题。例如,对于您的示例,这对应于
A = [1 2; 3 4; 4 5];
B = [0.5,0,0.5;0,1,0];
C = B*A
主要问题是以有效的方式从您的索引列表中构造B
。我的建议是使用 ==
的隐式扩展。
A = [1 2; 3 4; 4 5]; % Input data
idx = [1;2;1]; % Input Grouping
k = 2; % number of groups, ( = max(idx) )
m = 3; % Number of "observations"
Btmp = (idx == 1:k)'; % Mark locations
B = Btmp ./sum(Btmp,2); % Normalise
C = B*A
C =
2.5000 3.5000
3.0000 4.0000
【讨论】:
似乎 Btmp 可以更容易地构建:(idx == 1:k)'。这里应用了自动广播操作,所以不需要repmat。 @IhorDobrovolskyi,对,我一直忘记这一点,现在是一件事。你还记得是否有任何加速吗? 我不认为有任何合理的加速,但是它应该节省一些内存。 而且拥有更可读的代码也是使用自动广播的一个很好的理由,所以我一直更喜欢这种方式。以上是关于计算 Octave 中行组的列的平均值的主要内容,如果未能解决你的问题,请参考以下文章