是否有一个accumarray()将矩阵作为“val”?

时间:2010-12-03 23:07:32

标签: matlab matrix grouping accumarray

accumarray()val参数必须是向量。在我的情况下,我需要矩阵的列被求和(或平均)。是否有功能或方法来实现这一目标?

我现在正在做的是for循环我分别对列值进行求和:

for iCol = 1:nCols
    means(:,iCol) = accumarray(labels', X(:,iCol));
end

2 个答案:

答案 0 :(得分:9)

一种解决方案是复制labels中的行索引并添加另一列列索引。然后,您可以将X重新整形为列向量并应用accumarray一次:

labels = [repmat(labels(:),nCols,1) ...            % Replicate the row indices
          kron(1:nCols,ones(1,numel(labels))).'];  % Create column indices
totals = accumarray(labels,X(:));  % I used "totals" instead of "means"


工作原理......

A = accumarray(subs,val)列向量subs和向量val的工作原理是将val(i)中的数字添加到输出列向量中行subs(i)中的总数A。但是,subs可以包含的不仅仅是行索引。它可以包含多个维度的下标索引,以便在输出中指定值。此功能允许您处理输入val,它是矩阵而不是矢量。

首先,val的输入可以使用colon operator X(:)重新整形为列向量。接下来,为了跟踪输出中应该放置X(:)中的值的列,我们可以修改输入subs以包含其他列索引。为了说明这是如何工作的,我将使用这些示例输入:

labels = [3; 1; 1];
X = [1 2 3; ...
     4 5 6; ...
     7 8 9];
nCols = 3

以上代码中的变量最终看起来像:

labels = 3 1    X(:) = 1    totals = 11 13 15
         1 1           4              0  0  0
         1 1           7              1  2  3
         3 2           2
         1 2           5
         1 2           8
         3 3           3
         1 3           6
         1 3           9

请注意,例如,最初位于1 4 7的第一列中的值X将仅累积在输出的第一列中,如前三列中所示labels第二列的行。结果输出应该与您使用问题中的代码所获得的输出相同,您可以在每个列上循环执行累积。

答案 1 :(得分:1)

也许是从MATLAB Answers借用的一种更直观(也许更有效)的方式(原始答案假定是列主输入,所以我将它们换位了):

[xx, yy] = ndgrid(labels,1:size(X, 1));
totals = accumarray([yy(:) xx(:) ], reshape(X.', 1, []));

示例:

X = [1 2 3 4; 5 6 7 8];
labels = [2; 1; 3; 1];

给予 totals = [6 1 3; 14 5 7]

如果要逐行执行此操作,则无需转置,只需:

[xx, yy] = ndgrid(labels,1:size(X, 2));
totals = accumarray([xx(:) yy(:)], X(:));
相关问题