如何在MATLAB中通过列求和来分割矩阵元素?

21

有没有一种简单的方法可以将矩阵中的每个元素除以该列的总和?例如:

input:

1  4

4  10

output:

1/5  4/14

4/5  10/14
3个回答

43

以下是不同方法的列表,可以使用 bsxfun

  • ...

B = bsxfun(@rdivide,A,sum(A));
  • 使用repmat函数:

  • B = A./repmat(sum(A),size(A,1),1);
    
  • 使用外积(由Amro建议):

  • B = A./(ones(size(A,1),1)*sum(A));
    
  • ... 并且使用 for 循环(如 mtrw 建议的):

  • B = A;
    columnSums = sum(B);
    for i = 1:numel(columnSums)
      B(:,i) = B(:,i)./columnSums(i);
    end
    

    更新:

    从MATLAB R2016b版本开始,大多数内置的二进制函数(列表可以在这里找到)支持隐式扩展,这意味着它们默认具有bsxfun的行为。所以,在最新的MATLAB版本中,你只需要:

    B = A./sum(A);
    

    2
    你能不能为了完整性把循环加上呢? :) - mtrw
    2
    你可以将以下代码添加到列表中:B = A ./ (ones(size(A,1),1)*sum(A,1))。我认为它比repmat更快,但比bsxfun慢。 - Amro
    3
    非常感谢大家的帮助。我很好奇哪种方法是最快的。对于一个随机矩阵3000x3000,相对执行时间为(实验重复20次,持续时间求和):最快的是bsxfun(1.00),其次是loop(1.09),ones(1.99),repmat(2.06)。我将采用loop方法 :-)。 - danatel
    我刚刚做了一个测试,发现bsxfun是最快的。 - Nolan Conaway
    1
    自R2016b版本开始,您只需执行B = A./sum(A)即可。 - Navan
    显示剩余3条评论

    1
    a=[1 4;4 10]
    a =
         1     4
         4    10
    
    a*diag(1./sum(a,1))
    ans =
        0.2000    0.2857
        0.8000    0.7143
    

    +1,我喜欢这个。太遗憾了,它比“bsxfun”慢20倍。 - Stewie Griffin

    0

    忍不住尝试一下列表推导式。如果这个矩阵是以行主序的列表形式表示的,可以尝试这样做:

    >>> A = [[1,4],[4,10]]
    >>> [[float(i)/j for i,j in zip(a,map(sum,zip(*A)))] for a in A]
    [[0.20000000000000001, 0.2857142857142857], [0.80000000000000004, 0.7142857142857143]]
    

    是的,我知道这不是超级高效的,因为我们每行计算一次列和。将其保存在名为colsums的变量中看起来像:

    >>> colsums = map(sum,zip(*A))
    >>> [[float(i)/j for i,j in zip(a,colsums)] for a in A]
    [[0.20000000000000001, 0.2857142857142857], [0.80000000000000004, 0.7142857142857143]]
    

    请注意,zip(*A)会给出A的转置。

    哦,抱歉,是的。我没有注意到Matlab标签。 - PaulMcG

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