0

Each column of a matrix should sum to 1. In MATLAB I would write for a matrix mat

> mat = rand(5)

mat =
    0.2017    0.3976    0.0318    0.2750    0.2225
    0.0242    0.1222    0.1369    0.2883    0.3395
    0.0390    0.4260    0.2395    0.1462    0.2816
    0.0351    0.1851    0.2292    0.2386    0.3376
    0.1624    0.0157    0.2125    0.2813    0.2388

> mat = mat ./ ( ones(5,1) * sum(mat) )

mat = 
    0.4363    0.3467    0.0374    0.2237    0.1567
    0.0522    0.1066    0.1610    0.2345    0.2391
    0.0844    0.3715    0.2819    0.1189    0.1983
    0.0760    0.1614    0.2697    0.1941    0.2377
    0.3511    0.0137    0.2500    0.2288    0.1682

so that

> sum(mat)

ans = 
    1.0000    1.0000    1.0000    1.0000    1.0000

I hope this is an appropriate question for this site. Thanks.

user27886
  • 540
  • 12
  • 27
  • As a side note, in Matlab you'd better use the [more efficient approach](http://stackoverflow.com/questions/12951453/in-matlab-when-is-it-optimal-to-use-bsxfun) `mat = bsxfun(@rdivide, mat, sum(mat,1))` – Luis Mendo Nov 16 '14 at 16:10

2 Answers2

2

This operation can be written very concisely in numpy:

import numpy as np

mat = np.random.rand(5, 5)
mat /= mat.sum(0)
mat.sum(0) # will be array([ 1.,  1.,  1.,  1.,  1.])
Thibaut
  • 1,398
  • 10
  • 16
  • What are the general rules for the divide symbol? any good references? – user27886 Nov 16 '14 at 06:18
  • 1
    The rules are described in the [broadcasting](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) page: when doing an operation on two arrays of different sizes, numpy tries to reshape the arrays so that the operation is well-defined. Here we are trying to divide a 5x5 array by a 5x1 array. numpy will automatically repeat this array by stacking 5 identical rows on top of each other. – Thibaut Nov 16 '14 at 06:21
  • 1
    In `numpy` math operations normally operated element by element, where as in `matlab` you have to append the dot `.`. There is a `numpy` subclass (`matrix`) that behaves more like `matlab`. – hpaulj Nov 16 '14 at 17:50
  • 1
    Recent versions of `octave` also 'broadcast', so `mat ./ sum(mat)` works. I don't know if `matlab` has added this or not. – hpaulj Nov 16 '14 at 17:51
1

In NumPy you can do this by performing almost exactly the same operations:

>>> import numpy as np
>>> mat = np.random.rand(5, 5)
>>> new_mat = mat / (np.ones((5, 1)) * sum(mat))
>>> new_mat.sum(axis=0)
array([ 1.,  1.,  1.,  1.,  1.])
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504