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

如何在python中规范化一个二维numpy数组?,python,arrays,syntax,numpy,normalization,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]]) 为了规范化我想到的二维数组的行 row_sums = a.sum(axis=1) # array([ 9, 36, 63]) new_matrix = numpy.zeros((3,3)) for i, (row, row_sum) in enu

给定一个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]
行总和[:,numpy.newaxis]
将行总和从
(3,)
重塑为
(3,1)
。当您执行
a/b
时,
a
b
会相互广播


你可以了解更多关于广播的内容,甚至更好。

我认为这应该行得通

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

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

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。

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

验证:

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

看来这也行得通

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

或者使用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)

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

您也可以使用矩阵转置:

(a.T / row_sums).T

我认为您可以通过以下方式将行元素总和规格化为1:
new_matrix=a/a.sum(axis=1,keepdims=1)
。 可以使用
new_matrix=a/a.sum(axis=0,keepdims=1)
进行列规范化。希望这能有帮助

normed_matrix = normalize(input_data, axis=1, norm='l1')
print(normed_matrix)

如果input_data是2D阵列的名称,则可以使用内置的numpy函数:
np.linalg.norm(a,axis=1,keepdims=True)

以下是使用
重塑的另一种可能方法:

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

好。请注意,通过将小数点添加到27,将数据类型更改为arange。Axis似乎不是np.linalg.norm的参数(不再是了?)。值得注意的是,这对应于l2范数(其中,与1相加的行对应于l1范数),这可以使用
a.sum(Axis=1,keepdims=True)进一步简化
为了保持单例列维度,您可以在不使用
np.newaxis
的情况下播放该维度。如果任何行和为零,该怎么办?这是上述问题的正确答案-但是如果需要常规意义上的规范化,请使用
np.linalg.norm
而不是
a.sum
!这比行和更可取吗?重塑(3,1)
?因为行和可能为0,所以它没有那么稳健。小心,“规格化”通常意味着组件的平方和为1。你的定义对大多数人来说都不太清楚;)@coldfix谈到了
L2
norm,并认为它是最常见的(这可能是真的),而Aufwind使用
L1
norm,它实际上也是一个norm。这还有一个优点,即它在稀疏数组上工作,而稀疏数组不能作为密集数组装入内存。
array([[0.   , 0.333, 0.667],
       [0.25 , 0.333, 0.417],
       [0.286, 0.333, 0.381]])