【问题标题】:Multiply elements in second column according to labels in the first根据第一列中的标签将第二列中的元素相乘
【发布时间】:2015-01-05 15:55:50
【问题描述】:

我在 Matlab 中工作。 我有一个两列的二维矩阵。让我们将第一列中的元素视为标签。标签可能会重复。

如何将每个标签的第二列中的所有元素相乘?

例子:

matrix = [1,3,3,1,5; 2,3,7,8,3]'

我需要得到:

a = [1,3,5; 16,21,3]'

没有 for-while 循环你能帮我做吗?

【问题讨论】:

  • 为什么不允许使用for-loop?

标签: arrays matlab matrix vectorization


【解决方案1】:

我会使用accumarray。使用unique 的预处理将整数索引 1:n 分配给第一行中的值,这允许accumarray 工作而无需为 2 和 4 创建不必要的 bin。它还支持负数和浮点数。

[ulable,~,uindex]=unique(matrix(:,1))
r=accumarray(uindex,matrix(:,2),[],@prod)
r=[ulable,r]

/你也可以使用splitapply:

[ulable,~,uindex]=unique(matrix(:,1))
r=splitapply(@prod,matrix(:,2),uindex)
r=[ulable,r]

【讨论】:

  • 很好地使用了 accumarray 并且比我的解决方案 +1 干净得多 :)
  • unique+accumarray FTW!他们组成了一个伟大的团队。很好的解决方案。
【解决方案2】:

您可以使用accumarrayprod 函数在没有循环的情况下做到这一点:

clear
clc


matrix = [1,3,3,1,5; 2,3,7,8,3]';

A = unique(matrix,'rows');

group = A(:,1);

data = A(:,2);

indices = [group ones(size(group))];

prods = accumarray(indices, data,[],@prod); %// As mentionned by @Daniel. My previous answer had a function handle but there is no need for that here since prod is already defined in Matlab.

a = nonzeros(prods)

Out = [unique(group) a]

Out =

     1    16
     3    21
     5     3

查看 Lauren 的博文here,accumarray 非常有趣且功能强大!

【讨论】:

    【解决方案3】:

    试试这样的,我相信它可以改进......

    unValues = unique(matrix(:,1));
    bb = ones(size(unValues));
    
    for ii = 1:length(unValues)
        bb(ii) = bb(ii)*prod(matrix(matrix(:, 1) == unValues(ii), 2));
    end
    
    a = [unValues bb];
    

    【讨论】:

      猜你喜欢
      • 2016-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-17
      相关资源
      最近更新 更多