Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

numpy divide row by row sum

How can I divide a numpy array row by the sum of all values in this row?

This is one example. But I'm pretty sure there is a fancy and much more efficient way of doing this:

import numpy as np e = np.array([[0., 1.],[2., 4.],[1., 5.]]) for row in xrange(e.shape[0]):     e[row] /= np.sum(e[row]) 

Result:

array([[ 0.        ,  1.        ],        [ 0.33333333,  0.66666667],        [ 0.16666667,  0.83333333]]) 
like image 992
Stefan Profanter Avatar asked Apr 24 '13 21:04

Stefan Profanter


People also ask

How do you divide in NumPy?

divide(arr1, arr2, out = None, where = True, casting = 'same_kind', order = 'K', dtype = None) : Array element from first array is divided by elements from second element (all happens element-wise). Both arr1 and arr2 must have same shape and element in arr2 must not be zero; otherwise it will raise an error.

How do I divide a NumPy array by a constant?

Dividing a NumPy array by a constant is as easy as dividing two numbers. To divide each and every element of an array by a constant, use division arithmetic operator / . Pass array and constant as operands to the division operator as shown below. where a is input array and c is a constant.

Can you divide two NumPy arrays?

divide() is a numpy library function used to perform division amongst the elements of the first array by the elements of the second array. The process of division occurs element-wise between the two arrays. The numpy divide() function takes two arrays as arguments and returns the same size as the input array.


2 Answers

Method #1: use None (or np.newaxis) to add an extra dimension so that broadcasting will behave:

>>> e array([[ 0.,  1.],        [ 2.,  4.],        [ 1.,  5.]]) >>> e/e.sum(axis=1)[:,None] array([[ 0.        ,  1.        ],        [ 0.33333333,  0.66666667],        [ 0.16666667,  0.83333333]]) 

Method #2: go transpose-happy:

>>> (e.T/e.sum(axis=1)).T array([[ 0.        ,  1.        ],        [ 0.33333333,  0.66666667],        [ 0.16666667,  0.83333333]]) 

(You can drop the axis= part for conciseness, if you want.)

Method #3: (promoted from Jaime's comment)

Use the keepdims argument on sum to preserve the dimension:

>>> e/e.sum(axis=1, keepdims=True) array([[ 0.        ,  1.        ],        [ 0.33333333,  0.66666667],        [ 0.16666667,  0.83333333]]) 
like image 76
DSM Avatar answered Oct 19 '22 09:10

DSM


You can do it mathematically as enter image description here.

Here, E is your original matrix and D is a diagonal matrix where each entry is the sum of the corresponding row in E. If you're lucky enough to have an invertible D, this is a pretty mathematically convenient way to do things.

In numpy:

import numpy as np  diagonal_entries = [sum(e[row]) for row in range(e.shape[0])] D = np.diag(diagonal_entries) D_inv = np.linalg.inv(D) e = np.dot(e, D_inv) 
like image 31
Ali Avatar answered Oct 19 '22 08:10

Ali