Как нормализовать двумерный массив в Python менее многословно - PullRequest
78 голосов
/ 18 января 2012

Учитывая массив 3 раза 3

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

Должен быть лучший способ, не правда ли?t там?

Возможно, чтобы уточнить: Под нормализацией я подразумеваю, что сумма записей в строке должна быть одна.Но я думаю, что это будет понятно большинству людей.

Ответы [ 8 ]

116 голосов
/ 18 января 2012

Вещание действительно хорошо для этого:

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 транслируются друг против друга.

Вы можете узнать больше о вещании здесь или даже лучше здесь .

79 голосов
/ 21 марта 2014

Scikit-learn имеет функцию нормализации, которая позволяет применять различные нормализации."Make it sum to 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.

9 голосов
/ 18 января 2012

Я думаю, что это должно работать,

a = numpy.arange(0,27.,3).reshape(3,3)

a /=  a.sum(axis=1)[:,numpy.newaxis]
3 голосов
/ 10 мая 2014

В случае, если вы пытаетесь нормализовать каждую строку так, чтобы ее величина равнялась единице (то есть длина единицы строки равна единице или сумма квадрата каждого элемента в строке равна единице):

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 голос
/ 08 ноября 2015

похоже, что это тоже работает

def normalizeRows(M):
    row_sums = M.sum(axis=1)
    return M / row_sums
0 голосов
/ 16 октября 2018

Я думаю, вы можете нормализовать сумму элементов строки в 1 следующим образом: new_matrix = a / a.sum(axis=1, keepdims=1). А нормализацию столбца можно сделать с помощью new_matrix = a / a.sum(axis=0, keepdims=1). Надеюсь, что это может помочь.

0 голосов
/ 21 февраля 2017

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

(a.T / row_sums).T
0 голосов
/ 12 января 2017

Или с использованием лямбда-функции, например

>>> 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 будет иметь единичную норму.

...