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

发布于 2024-10-05 22:46:19 字数 316 浏览 3 评论 0原文

accumarray()val 参数必须是一个向量。就我而言,我需要对矩阵的列进行求和(或平均)。有没有一个函数或方法可以实现这一点?

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

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

accumarray()'s val argument must be a vector. In my case I need columns of a matrix to be summed (or averaged). Is there a function or a method to achieve this?

What I am doing now is in a for loop I am summing column values separately:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

海未深 2024-10-12 22:46:19

一种解决方案是复制标签中的行索引并添加另一列列索引。然后,您可以将 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

首先,可以使用 冒号运算符 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 第二列前三行中的值所示。生成的输出应该与使用问题中的代码(循环遍历每列以执行累积)得到的输出相同。

One solution is to replicate the row indices in labels and add another column of column indices. Then you can reshape X into a column vector and apply accumarray once:

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"

How it works...

A = accumarray(subs,val) for a column vector subs and vector val works by adding the number in val(i) to the total in row subs(i) in the output column vector A. However, subs can contain more than just row indices. It can contain subscript indices for multiple dimensions to assign values to in the output. This feature is what allows you to handle an input val that is a matrix instead of a vector.

First, the input for val can be reshaped into a column vector using the colon operator X(:). Next, in order to keep track of which column in the output the values in X(:) should be placed, we can modify the input subs to include an additional column index. To illustrate how this works, I'll use these sample inputs:

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

And here are what the variables in the above code end up looking like:

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

Notice, for example, that the values 1 4 7 that were originally in the first column of X will only be accumulated in the first column of the output, as denoted by the ones in the first three rows of the second column of labels. The resulting output should be the same as what you would have gotten by using the code in the question where you loop over each column to perform the accumulation.

神也荒唐 2024-10-12 22:46:19

也许是从 MATLAB 答案(原始答案假设列主输入,因此我转置它们):

[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];

给出
总计 = [6 1 3; 14 5 7]

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

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

Perhaps a more intuitive (maybe more efficient) way borrowed from MATLAB Answers (the original answer assumes column-major inputs so I transposed them):

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

Example:

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

gives
totals = [6 1 3; 14 5 7].

If you want to do this row-wise then there's no need to transpose, just:

[xx, yy] = ndgrid(labels,1:size(X, 2));
totals = accumarray([xx(:) yy(:)], X(:));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文