2013-04-24 34 views
26

Làm cách nào để có thể chia hàng mảng numpy bằng tổng của tất cả các giá trị trong hàng này?hàng chia nhỏ theo hàng tổng cộng

Đây là một ví dụ. Nhưng tôi chắc rằng có một cách lạ mắt và nhiều hiệu quả hơn để làm điều này:

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

Kết quả:

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

Trả lời

53

Phương pháp # 1: sử dụng None (hoặc np.newaxis) để thêm thêm một chiều hướng để phát sóng mà sẽ cư xử:

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

Phương pháp # 2: đi transpose-hạnh phúc:

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

(Bạn có thể thả các phần axis= cho conciseness, nếu bạn muốn.)

Phương pháp # 3: (thăng từ bình luận của Jaime)

Sử dụng keepdims luận trên sum để duy trì kích thước:

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

tôi không thấy làm thế nào bạn có thể thả 'trục = 1'. Không có đối số 'axis',' sum() 'trả về tổng của tất cả các giá trị trong mảng. –

+18

Trong numpy 1.7 có một đối số 'keepdims' cho phép bạn thực hiện' e/e.sum (axis = 1, keepdims = True) ' – Jaime

+2

@WarrenWeckesser: Tôi không nói bạn có thể bỏ phần' 1', tôi cho biết bạn có thể thả phần 'axis ='. – DSM

5

Bạn có thể thực hiện toán học theo số enter image description here.

Ở đây, E là ma trận gốc của bạn và D là ma trận đường chéo trong đó mỗi mục nhập là tổng của hàng tương ứng trong E. Nếu bạn đủ may mắn để có một không thể đảo ngược D, đây là một cách khá thuận tiện về mặt toán học để làm việc.

Trong 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) 
Các vấn đề liên quan