21

Is there an easy way to divide each matrix element by the column sum? For example:

input:

1  4

4  10

output:

1/5  4/14

4/5  10/14
gnovice
  • 125,304
  • 15
  • 256
  • 359
danatel
  • 4,844
  • 11
  • 48
  • 62

3 Answers3

43

Here's a list of the different ways to do this ...

  • ... using bsxfun:

    B = bsxfun(@rdivide,A,sum(A));
    
  • ... using repmat:

    B = A./repmat(sum(A),size(A,1),1);
    
  • ... using an outer product (as suggested by Amro):

    B = A./(ones(size(A,1),1)*sum(A));
    
  • ... and using a for loop (as suggested by mtrw):

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

Update:

As of MATLAB R2016b and later, most built-in binary functions (list can be found here) support implicit expansion, meaning they have the behavior of bsxfun by default. So, in the newest MATLAB versions, all you have to do is:

B = A./sum(A);
Community
  • 1
  • 1
gnovice
  • 125,304
  • 15
  • 256
  • 359
  • 2
    Can't you throw the loop in just for completeness? :) – mtrw Nov 20 '09 at 20:52
  • 2
    you can add this to the list: `B = A ./ (ones(size(A,1),1)*sum(A,1))`. I think its faster than *repmat* but slower than *bsxfun* – Amro Nov 20 '09 at 23:45
  • @Amro - nice, I hadn't thought of that one. – mtrw Nov 21 '09 at 00:41
  • 3
    Thank you all very much for your help. I was curious which method is the fastest. Relative execution times are (applied to random matrix 3000x3000; experiment repeated 20 times; duration summed) fastest bsxfun (1.00), loop (1.09), ones (1.99), repmat (2.06). I am going to use the loop method :-). – danatel Nov 21 '09 at 12:45
  • bsxfun is better than a loop IMHO. Looks more functional. – joaomilho Sep 11 '12 at 12:42
  • Loop in MATLAB is a very bad idea. REPMAT and outer product look like the same thing. I did a tic toc analysis of these - RIPMAT is the fastest, followed by outer product followed by the anonymous function. Did not bother with the loop at all. (Tested on 2015a). size(A) = [25,1] – Lord Loh. Sep 16 '15 at 18:26
  • I just did a test and found bsxfun is the fastest. – Nolan Conaway Oct 22 '15 at 02:03
  • 1
    Since R2016b, you can just do B = A./sum(A). – Navan Nov 04 '16 at 13:17
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
Stewie Griffin
  • 14,889
  • 11
  • 39
  • 70
0

Couldn't resist trying a list comprehension. If this matrix was represented in a row-major list of lists, try this:

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

Yes, I know that this is not super-efficient, as we compute the column sums once per row. Saving this in a variable named colsums looks like:

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

Note that zip(*A) gives transpose(A).

PaulMcG
  • 62,419
  • 16
  • 94
  • 130