我有一个22007x3
矩阵,第3列有数据,第1列和第2列有两个独立的索引。
例如
x =
1 3 4
1 3 5
1 3 5
1 16 4
1 16 3
1 16 4
2 4 1
2 4 3
2 11 2
2 11 3
2 11 2
当第1列中的值相同且第2列中的值相同时,我需要找到第3列中值的平均值,以得到类似的结果:
ans =
1 3 4.6667
1 16 3.6667
2 4 2
2 11 2.3333
请记住,在我的数据中,第1列和第2列中的值出现的次数可能不同。
我已尝试过的两个选项是meshgrid
/ accumarray
选项,使用两个不同的unique
函数和一个3D数组:
[U, ix, iu] = unique(x(:, 1));
[U2,ix2,iu2] = unique(x(:,2));
[c, r, j] = meshgrid((1:size(x(:, 1), 2)), iu, iu2);
totals = accumarray([r(:), c(:), j(:)], x(:), [], @nanmean);
给了我这个:
??? Maximum variable size allowed by the program is exceeded.
Error in ==> meshgrid at 60
xx = xx(ones(ny,1),:,ones(nz,1));
和循环选项,
for i=1:size(x,1)
if x(i,2)== x(i+1,2);
totals(i,:)=accumarray(x(:,1),x(:,3),[],@nanmean);
end
end
这显然是非常非常错误的,尤其是因为x(i+1,2)
位。
我也在考虑根据第1列中的值出现次数来创建单独的矩阵,但这样做会很长且效率很低,所以我不愿意走这条路。
答案 0 :(得分:5)
在前两列上使用unique(...,'rows')
进行分组,然后仅累积第三列(始终是仅在积累真正发生的地方积累的最佳方法,从而避免索引,即第一列两列,您可以使用unX
重新附加):
[unX,~,subs] = unique(x(:,1:2),'rows');
out = [unX accumarray(subs,x(:,3),[],@nanmean)];
out =
1 3 4.6667
1 16 3.6667
2 4 2
2 11 2.33
答案 1 :(得分:1)
这是使用稀疏矩阵数学的理想机会。
x = [ 1 2 5;
1 2 7;
2 4 6;
3 4 6;
1 4 8;
2 4 8;
1 1 10]; % for example
SM = sparse(x(:,1),x(:,2), x(:,3);
disp(SM)
结果:
(1,1) 10
(1,2) 12
(1,4) 8
(2,4) 14
(3,6) 7
正如你所看到的,我们一举“将相同的指数累积到同一个容器中”。现在你需要知道你有多少元素:
NE = sparse(x(:,1), x(:,2), ones(size(x(:,1))));
disp(NE);
结果:
(1,1) 1
(1,2) 2
(1,4) 1
(2,4) 2
(3,6) 1
最后,你将一个除以另一个来得到均值(仅使用具有值的元素):
matrixMean = SM;
nz = find(NE>0);
matrixMean(nz) = SM(nz) ./ NE(nz);
如果你然后disp(matrixMean)
,你得到
(1,1) 10
(1,2) 6
(1,4) 8
(2,4) 7
(3,6) 7
如果您想以不同方式访问各个元素,那么在计算完SM和NE后,您可以
[i j n] = find(NE);
matrixMean = SM(i,j)./NE(i,j);
disp([i(:) j(:) nonzeros(matrixMean)]);