匹配首元素的矩阵行求和?

3

我有一个矩阵:

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

我希望通过将第一列元素匹配的行的第二列相加来简化它。因此,上述矩阵a应变为:

a=[1 7
   2 12
   3 4];

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


*[...]将第一列元素匹配的行的第二列相加。请澄清/重新表述。 - jub0bs
我的意思是,如果它们第一列的元素匹配,我想将行相加。例如,行[1 2][1 3]应该被加在一起(因为两者都在第一列中有1),但是行[1 2][2 4]不应该被加在一起(因为一个在第一列中有1,而另一个在第一列中有2...) - space_voyager
2
你的输出示例中 1 5 是错误的输出,不是吗? - Robert Seifert
非常感谢,已经进行了编辑。 - space_voyager
1个回答

6
使用 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
我不知道一个简单的解决方案,可以把它放在一行里。 - Robert Seifert
如果你的第一列总是包含整数1、2、3...(以任何顺序,但从1开始且没有任何间隙),那么你就不需要使用unique,因此你可以使用单行代码out = [ (1:max(a(:,1))).' accumarray(a(:,1),a(:,2)) ] - Luis Mendo
@LuisMendo 我的第一个回答是:out = [ unique(a(:,1)) accumarray(a(:,1),a(:,2)) ] - 但我将其编辑掉了,因为它只适用于你提到的情况。由于编辑太早,所以它没有出现在修订历史记录中。 - Robert Seifert
非常感谢这些建议! - space_voyager

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接