如何简化地规范化Python中的二维numpy数组?

119 投票
12 回答
269235 浏览
提问于 2025-04-17 10:29

给定一个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

应该有更好的方法,对吧?

也许我再解释一下:归一化的意思是每一行的数值加起来必须等于1。不过我想这对大多数人来说应该是很清楚的。

12 个回答

11

我觉得这个应该可以用。

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

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

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

现在你的每一行的总和都会变成1。

177

广播(Broadcasting)在这里非常有用:

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

row_sums[:, numpy.newaxis] 这段代码把 row_sums 从原来的形状 (3,) 变成了 (3, 1)。当你进行 a / b 的运算时,ab 会相互“广播”,也就是自动调整形状以便进行计算。

你可以在 这里 了解更多关于广播的内容,或者更详细的信息可以查看 这里

撰写回答