计算 Octave 中行组的列平均值
Compute mean of columns for groups of rows in Octave
我有一个矩阵,例如:
1 2
3 4
4 5
而且我还有一个对行进行分组的规则,它被定义为一组 ID 的向量,如下所示:
1
2
1
这意味着第一行和第三行属于同一组(ID 1),第二行属于另一个组(ID 2)。所以,我想计算每组的平均值。这是我的示例的结果:
2.5 3.5
3 4
更正式地说,有一个大小为 A 的矩阵 (m, n) , 一些组 k 和一个向量 v 大小 (m, 1), 值它们是 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), :);
你可以把它看成一个矩阵乘法问题。例如,对于您的示例,这对应于
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
只要我们的数据是浮点型的,你可以自己做加法然后除法,利用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
我有一个矩阵,例如:
1 2
3 4
4 5
而且我还有一个对行进行分组的规则,它被定义为一组 ID 的向量,如下所示:
1
2
1
这意味着第一行和第三行属于同一组(ID 1),第二行属于另一个组(ID 2)。所以,我想计算每组的平均值。这是我的示例的结果:
2.5 3.5
3 4
更正式地说,有一个大小为 A 的矩阵 (m, n) , 一些组 k 和一个向量 v 大小 (m, 1), 值它们是 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), :);
你可以把它看成一个矩阵乘法问题。例如,对于您的示例,这对应于
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
只要我们的数据是浮点型的,你可以自己做加法然后除法,利用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