2013-04-24 15 views
26

Jak mogę podzielić wiersz tablicy numpy przez sumę wszystkich wartości w tym wierszu?numpy podzielić wiersz po wierszu suma

To jest jeden przykład. Ale jestem prawie pewien, że jest to wyszukane i znacznie bardziej efektywny sposób to zrobić:

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

Wynik:

array([[ 0.  , 1.  ], 
     [ 0.33333333, 0.66666667], 
     [ 0.16666667, 0.83333333]]) 

Odpowiedz

53

Sposób nr 1: użyj None (lub np.newaxis), aby dodać dodatkowy wymiar tak, że transmisja będzie zachowywać:

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

Sposób nr 2: przejdź transpozycji-happy:

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

(można upuścić axis= część dla zwięzłości, jeśli chcesz).

Sposób nr 3: (awans z komentarzem Jaime)

Użyj keepdims argumentem na sum zachować wymiar:

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

nie widzę w jaki sposób można upuścić 'oś = 1 '. Bez argumentu "osi", 'sum()' zwraca sumę wszystkich wartości w tablicy. –

+18

W numpy 1.7 znajduje się argument "keepdims", który pozwala ci na 'e/e.sum (axis = 1, keepdims = True)' – Jaime

+2

@WarrenWeckesser: Nie powiedziałem, że możesz upuścić część '1', I powiedział, że możesz upuścić część 'axis ='. – DSM

5

Możesz to zrobić matematycznie jako enter image description here.

Tutaj, E jest oryginalną macierzą, a D jest macierzą diagonalną, w której każdy wpis jest sumą odpowiedniego wiersza w E. Jeśli masz szczęście mieć odwracalny D, jest to dość matematycznie wygodny sposób robienia rzeczy.

W 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) 
Powiązane problemy