Подтвердить что ты не робот

Numpy разделите строку за строкой sum

Как я могу разделить строку массива numpy на сумму всех значений в этой строке?

Это один из примеров. Но я уверен, что есть причудливый и гораздо более эффективный способ сделать это:

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

Результат:

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

Ответ 1

Метод # 1: используйте None (или np.newaxis), чтобы добавить дополнительное измерение, чтобы вести себя в режиме вещания:

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

Метод # 2: перейдите в режим транспонирования:

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

(Вы можете отбросить часть axis= для краткости, если хотите.)

Метод № 3: (продвигается из комментария Хайме)

Используйте аргумент keepdims на sum, чтобы сохранить размер:

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

Ответ 2

Вы можете сделать это математически как введите описание изображения здесь.

Здесь E - ваша исходная матрица, а D - диагональная матрица, где каждая запись представляет собой сумму соответствующей строки в E. Если вам повезло иметь обратимый D, это довольно математически удобный способ сделать что-то.

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