How to normalize a 2-dimensional numpy array in python less verbose?

Given a 3x 3 dimensional array

a = numpy.arange(0,27,3).reshape(3,3) # array([[ 0, 3, 6], # [ 9, 12, 15], # [18, 21, 24]]) 

To normalize the rows of a two-dimensional array, I was thinking about

 row_sums = a.sum(axis=1) # array([ 9, 36, 63]) new_matrix = numpy.zeros((3,3)) for i, (row, row_sum) in enumerate(zip(a, row_sums)): new_matrix[i,:] = row / row_sum 

There must be a better way, right?

Perhaps to clear: by normalization, I mean that the sum of the entries in the row should be one. But I think that it will be clear to most people.

+80
python arrays syntax numpy normalization
Jan 18 '12 at 3:12
source share
7 answers

Broadcasting is really useful for this:

 row_sums = a.sum(axis=1) new_matrix = a / row_sums[:, numpy.newaxis] 

row_sums[:, numpy.newaxis] changes row_sums from (3,) to (3, 1) . When you do a / b , a and b broadcast against each other.

You can learn more about the broadcast here or even better here .

+121
Jan 18 '12 at 3:21
source share

Scikit-learn has a normalization function that allows you to apply various normalizations. "Make a sum of up to 1" is the norm of L1, and do this:

 from sklearn.preprocessing import normalize matrix = numpy.arange(0,27,3).reshape(3,3).astype(numpy.float64) #array([[ 0., 3., 6.], # [ 9., 12., 15.], # [ 18., 21., 24.]]) normed_matrix = normalize(matrix, axis=1, norm='l1') #[[ 0. 0.33333333 0.66666667] #[ 0.25 0.33333333 0.41666667] #[ 0.28571429 0.33333333 0.38095238]] 

Now your lines will be added up to 1.

+83
Mar 20 '14 at 22:54
source share

I think it should work

 a = numpy.arange(0,27.,3).reshape(3,3) a /= a.sum(axis=1)[:,numpy.newaxis] 
+9
Jan 18 '12 at 3:22
source share

If you are trying to normalize each row so that its value is one (i.e. the length of the row unit is equal to one or the sum of the square of each element in the row is one):

 import numpy as np a = np.arange(0,27,3).reshape(3,3) result = a / np.linalg.norm(a, axis=-1)[:, np.newaxis] # array([[ 0. , 0.4472136 , 0.89442719], # [ 0.42426407, 0.56568542, 0.70710678], # [ 0.49153915, 0.57346234, 0.65538554]]) 

Verification:

 np.sum( result**2, axis=-1 ) # array([ 1., 1., 1.]) 
+3
May 10 '14 at 19:13
source share

it looks like it also works

 def normalizeRows(M): row_sums = M.sum(axis=1) return M / row_sums 
+1
Nov 08 '15 at 15:13
source share

Or using a lambda function, for example

 >>> vec = np.arange(0,27,3).reshape(3,3) >>> import numpy as np >>> norm_vec = map(lambda row: row/np.linalg.norm(row), vec) 

each vec vector will have a unit norm.

0
Jan 12 '17 at 9:31 on
source share

You can also use matrix transfer:

 (aT / row_sums).T 
0
Feb 21 '17 at 11:20
source share



All Articles