Учитывая 3 раза 3 массива numpy
a = numpy.arange(0,27,3).reshape(3,3)
# array([[ 0, 3, 6],
# [ 9, 12, 15],
# [18, 21, 24]])
Чтобы нормализовать строки двумерного массива, я подумал о
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
Должен быть способ получше, не так ли?
Возможно, чтобы прояснить: под нормализацией я имею в виду, что сумма записей в строке должна быть равна единице. Но я думаю, это будет понятно большинству людей.
Ответы:
Трансляция для этого действительно хороша:
row_sums = a.sum(axis=1) new_matrix = a / row_sums[:, numpy.newaxis]
row_sums[:, numpy.newaxis]
преобразует row_sums из бытия(3,)
в бытие(3, 1)
. Когда вы это делаетеa / b
,a
иb
транслируются друг против друга.Вы можете узнать больше о трансляциях здесь или даже лучше здесь .
источник
a.sum(axis=1, keepdims=True)
упростить, сохранив измерение одноэлементного столбца, которое затем можно транслировать без необходимости использованияnp.newaxis
.np.linalg.norm
вместоa.sum
!row_sums.reshape(3,1)
?Scikit-learn имеет функцию нормализации, которая позволяет применять различные нормализации. «Сделать сумму до 1» - это норма L1, и для этого нужно:
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]]
Теперь сумма ваших строк будет равна 1.
источник
Я думаю, это должно сработать,
a = numpy.arange(0,27.,3).reshape(3,3) a /= a.sum(axis=1)[:,numpy.newaxis]
источник
В случае, если вы пытаетесь нормализовать каждую строку так, чтобы ее величина была равна единице (т.е. единичная длина строки равна единице или сумма квадратов каждого элемента в строке равна единице):
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]])
Проверка:
np.sum( result**2, axis=-1 ) # array([ 1., 1., 1.])
источник
Я думаю , что вы можете нормализовать сумму ряда элементов 1 этим:
new_matrix = a / a.sum(axis=1, keepdims=1)
. А нормализацию столбца можно выполнить с помощьюnew_matrix = a / a.sum(axis=0, keepdims=1)
. Надеюсь, это может помочь.источник
Вы можете использовать встроенную функцию numpy:
np.linalg.norm(a, axis = 1, keepdims = True)
источник
похоже, что это тоже работает
def normalizeRows(M): row_sums = M.sum(axis=1) return M / row_sums
источник
Вы также можете использовать транспонирование матрицы:
источник
Или используя лямбда-функцию, например
>>> vec = np.arange(0,27,3).reshape(3,3) >>> import numpy as np >>> norm_vec = map(lambda row: row/np.linalg.norm(row), vec)
каждый вектор vec будет иметь единичную норму.
источник
Вот еще один возможный способ использования
reshape
:a_norm = (a/a.sum(axis=1).reshape(-1,1)).round(3) print(a_norm)
Или с помощью
None
тоже работает:a_norm = (a/a.sum(axis=1)[:,None]).round(3) print(a_norm)
Выход :
array([[0. , 0.333, 0.667], [0.25 , 0.333, 0.417], [0.286, 0.333, 0.381]])
источник
normed_matrix = normalize(input_data, axis=1, norm='l1') print(normed_matrix)
где input_data - это имя вашего 2D-массива
источник