如何规范化python中的二维numpy数组更简洁?

Auf*_*ind 81 python arrays syntax numpy normalization

给出3次3 numpy阵列

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

# array([[ 0,  3,  6],
#        [ 9, 12, 15],
#        [18, 21, 24]])
Run Code Online (Sandbox Code Playgroud)

为了规范化我想到的二维数组的行

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
Run Code Online (Sandbox Code Playgroud)

必须有更好的方法,不是吗?

也许要澄清:通过归一化我的意思是,每行的总和必须是1.但我认为大多数人都会清楚这一点.

Bi *_*ico 123

广播对此非常有益:

row_sums = a.sum(axis=1)
new_matrix = a / row_sums[:, numpy.newaxis]
Run Code Online (Sandbox Code Playgroud)

row_sums[:, numpy.newaxis]将row_sums重塑(3,)为存在(3, 1).当你这样做a / b,ab互相广播.

您可以了解更多关于广播 在这里,甚至更好这里.

  • 使用`a.sum(axis = 1,keepdims = True)`可以进一步简化这一点,以保持单例列维度,然后可以在不必使用`np.newaxis`的情况下进行广播. (22认同)
  • 这是上述问题的正确答案 - 但如果需要通常意义上的规范化,请使用`np.linalg.norm`而不是`a.sum`! (7认同)
  • 如果任何row_sums为零怎么办? (5认同)
  • 这比`row_sums.reshape(3,1)`更受欢迎吗? (2认同)

rog*_*err 86

Scikit-learn有一个normalize函数,可以让你应用各种规范化."使它总和为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]]
Run Code Online (Sandbox Code Playgroud)

现在你的行总和为1.

  • 这还有一个优点,即它适用于稀疏数组,而稀疏数组不能像密集数组一样装入内存。 (3认同)

tom*_*m10 9

我认为这应该有用,

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

a /=  a.sum(axis=1)[:,numpy.newaxis]
Run Code Online (Sandbox Code Playgroud)

  • 好.注意通过将小数点后加到27来将dtype更改为arange. (2认同)

wal*_*alt 6

如果您尝试对每一行进行归一化,使其大小为 1(即,一行的单位长度为 1,或者一行中每个元素的平方和为 1):

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]])
Run Code Online (Sandbox Code Playgroud)

验证:

np.sum( result**2, axis=-1 )
# array([ 1.,  1.,  1.]) 
Run Code Online (Sandbox Code Playgroud)