如何在python中规范化一个二维的numpy数组?

时间:2022-06-20 21:44:55

Given a 3 times 3 numpy array

给定一个3乘以3的numpy数组

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

# array([[ 0,  3,  6],
#        [ 9, 12, 15],
#        [18, 21, 24]])

To normalize the rows of the 2-dimensional array I thought of

将二维数组的行规范化

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

There must be a better way, isn't there?

一定有更好的办法,不是吗?

Perhaps to clearify: By normalizing I mean, the sum of the entrys per row must be one. But I think that will be clear to most people.

也许是为了澄清:通过规范化,我的意思是,每行的入口之和必须是1。但我想大多数人都会明白这一点。

7 个解决方案

#1


91  

Broadcasting is really good for this:

广播真的很好:

row_sums = a.sum(axis=1)
new_matrix = a / row_sums[:, numpy.newaxis]

row_sums[:, numpy.newaxis] reshapes row_sums from being (3,) to being (3, 1). When you do a / b, a and b are broadcast against each other.

numpy row_sums[:。将row_sum从(3,)重设为(3,1).当执行a / b时,a和b会相互广播。

You can learn more about broadcasting here or even better here.

你可以在这里学到更多,甚至更好。

#2


61  

Scikit-learn has a normalize function that lets you apply various normalizations. The "make it sum to 1" is the L1 norm, and to take that do:

scikitt -learn有一个规范化函数,允许您应用各种规范化。L1范数是“使它与1相加”。

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

Now your rows will sum to 1.

现在你的行和是1。

#3


7  

I think this should work,

我认为这应该行得通,

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

a /=  a.sum(axis=1)[:,numpy.newaxis]

#4


1  

it appears that this also works

这似乎也行得通

def normalizeRows(M):
    row_sums = M.sum(axis=1)
    return M / row_sums

#5


0  

In case you are trying to normalize each row such that its magnitude is one (i.e. a row's unit length is one or the sum of the square of each element in a row is one):

如果你试图使每一行标准化,这样它的大小是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]])

Verifying:

验证:

np.sum( result**2, axis=-1 )
# array([ 1.,  1.,  1.]) 

#6


0  

Or using lambda function, like

或者使用lambda函数,比如。

>>> vec = np.arange(0,27,3).reshape(3,3)
>>> import numpy as np
>>> norm_vec = map(lambda row: row/np.linalg.norm(row), vec)

each vector of vec will have a unit norm.

vec的每个向量都有一个单位范数。

#7


0  

You could also use matrix transposition:

你也可以使用矩阵变换:

(a.T / row_sums).T

#1


91  

Broadcasting is really good for this:

广播真的很好:

row_sums = a.sum(axis=1)
new_matrix = a / row_sums[:, numpy.newaxis]

row_sums[:, numpy.newaxis] reshapes row_sums from being (3,) to being (3, 1). When you do a / b, a and b are broadcast against each other.

numpy row_sums[:。将row_sum从(3,)重设为(3,1).当执行a / b时,a和b会相互广播。

You can learn more about broadcasting here or even better here.

你可以在这里学到更多,甚至更好。

#2


61  

Scikit-learn has a normalize function that lets you apply various normalizations. The "make it sum to 1" is the L1 norm, and to take that do:

scikitt -learn有一个规范化函数,允许您应用各种规范化。L1范数是“使它与1相加”。

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

Now your rows will sum to 1.

现在你的行和是1。

#3


7  

I think this should work,

我认为这应该行得通,

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

a /=  a.sum(axis=1)[:,numpy.newaxis]

#4


1  

it appears that this also works

这似乎也行得通

def normalizeRows(M):
    row_sums = M.sum(axis=1)
    return M / row_sums

#5


0  

In case you are trying to normalize each row such that its magnitude is one (i.e. a row's unit length is one or the sum of the square of each element in a row is one):

如果你试图使每一行标准化,这样它的大小是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]])

Verifying:

验证:

np.sum( result**2, axis=-1 )
# array([ 1.,  1.,  1.]) 

#6


0  

Or using lambda function, like

或者使用lambda函数,比如。

>>> vec = np.arange(0,27,3).reshape(3,3)
>>> import numpy as np
>>> norm_vec = map(lambda row: row/np.linalg.norm(row), vec)

each vector of vec will have a unit norm.

vec的每个向量都有一个单位范数。

#7


0  

You could also use matrix transposition:

你也可以使用矩阵变换:

(a.T / row_sums).T