【问题标题】:Sum rows in matrix whose first elements match?矩阵中第一个元素匹配的行求和?
【发布时间】:2015-09-04 09:56:58
【问题描述】:

我有矩阵:

a=[1 2
   2 3
   1 5
   3 4
   2 9];

我想通过将第一列元素匹配的第二列行相加来简化它。因此上面的矩阵a应该变成:

a=[1 7
   2 12
   3 4];

我不知道如何在功能上做到这一点,换句话说,没有 for 循环。谢谢!

【问题讨论】:

  • [...] 将第一列元素匹配的行的第二列相加。请澄清/重新表述。
  • 我的意思是,如果第一列中的元素匹配,我想将行加在一起。例如,[1 2][1 3] 行应该加在一起(因为第一列都有 1)但 [1 2][2 4] 行应该加在一起(因为一个在第一列有 1,另一个有 2...)
  • 我会说你的示例输出中的1 5 是错误的输出,不是吗?
  • 非常感谢,进行了编辑。

标签: arrays matlab matrix


【解决方案1】:

使用accumarrayunique

[u,~,subs] = unique(a(:,1))
out = [ u, accumarray(subs,a(:,2)) ]

out =

     1     7
     2    12
     3     4

对于单行解决方案,您需要一个外部函数:

function subs = unique3rdOutput( vec )
   [~,~,subs] = unique(vec)

然后

out = [ unique(a(:,1)), accumarray(unique3rdOutput(a(:,1)),a(:,2)) ]

如果您可以确保第一列中只有正整数,您还可以使用:

out = [ unique(a(:,1)) accumarray(a(:,1),a(:,2)) ]

或按照 Luis Mendo 的建议:

out = [ (1:max(a(:,1))).' accumarray(a(:,1),a(:,2)) ]

【讨论】:

  • 太棒了,非常适合您的最终编辑。我想知道,是否可以让unique 直接返回subs,这样我就可以将整个内容写在一行上?我只是出于好奇而询问(我意识到这种方式效率会降低,因为我必须调用两次unique,一次生成u,一次生成subs)因为也许它会在某些应用程序中对我有用。
  • 我不知道有一种简单的解决方案可以将它放在一行中。
  • @space_voyager 如果 你的第一列总是包含整数 1, 2, 3,...(以任何顺序,但从 1 开始并且没有任何间隙)你不需要unique,所以你可以有一行out = [ (1:max(a(:,1))).' accumarray(a(:,1),a(:,2)) ]
  • @LuisMendo 我的第一个答案是:out = [ unique(a(:,1)) accumarray(a(:,1),a(:,2)) ] - 但我编辑了它,因为它只适用于你提到的情况。它不在修订历史中,因为编辑来得早。
  • 非常感谢这些建议!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-24
  • 1970-01-01
相关资源
最近更新 更多