13

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

我现在正在做的是在一个 for 循环中,我分别对列值求和:

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

2 回答 2

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的工作原理是将 in 添加到输出列向量val(i)的行中的总数中。但是,可以包含的不仅仅是行索引。它可以包含多个维度的下标索引以在输出中分配值。此功能允许您处理作为矩阵而不是向量的输入。subs(i)Asubsval

首先,可以使用冒号运算符将for 的输入val重新整形为列向量。接下来,为了跟踪输出中应该放置值的列,我们可以修改输入以包含一个额外的列索引。为了说明这是如何工作的,我将使用这些示例输入: 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。结果输出应该与使用问题中的代码获得的输出相同,在该问题中循环遍历每一列以执行累加。

于 2010-12-04T00:19:19.137 回答
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(:));
于 2018-11-11T21:09:57.307 回答