1

我有一个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 列中的值出现的次数创建单独的矩阵,但这会很长而且效率低下,所以我不愿意走这条路。

4

2 回答 2

5

用 a 对前两列进行分组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
于 2013-04-19T15:26:56.180 回答
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)]);
于 2013-04-19T17:37:53.237 回答