views:

377

answers:

2

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
+11  A: 

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
    
gnovice
Can't you throw the loop in just for completeness? :)
mtrw
@mtrw: Yes, yes I can. ;)
gnovice
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
@Amro - nice, I hadn't thought of that one.
mtrw
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
A: 

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).

Paul McGuire
Is that Python?
gnovice
Oh, sorry, yes it is. I didn't notice the Matlab tag.
Paul McGuire

related questions