【问题标题】:How to normalize a 2-dimensional numpy array in python less verbose?如何在 python 中规范化二维 numpy 数组?
【发布时间】:2012-02-12 20:25:47
【问题描述】:

给定一个 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。但我认为大多数人都清楚这一点。

【问题讨论】:

  • 小心,“归一化”通常意味着 平方 分量的和为 1。大多数人都很难清楚你的定义;)
  • @coldfix 谈到 L2 norm 并认为它是最常见的(这可能是真的),而 Aufwind 使用 L1 norm 这也是一个规范。

标签: python arrays syntax numpy normalization


【解决方案1】:

广播对此非常有用:

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 会相互广播。

您可以了解更多关于广播 here 甚至更好的here

【讨论】:

  • 这可以进一步简化,使用a.sum(axis=1, keepdims=True) 保持单列维度,然后您可以在不必使用np.newaxis 的情况下进行广播。
  • 如果任何 row_sum 为零怎么办?
  • 这是上述问题的正确答案 - 但如果需要通常意义上的标准化,请使用 np.linalg.norm 而不是 a.sum
  • 这是首选 row_sums.reshape(3,1) 吗?
  • 它没有那么健壮,因为行总和可能为 0。
【解决方案2】:

我认为这应该可行,

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

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

【讨论】:

  • 好。注意将 dtype 更改为 arange,将小数点附加到 27。
【解决方案3】:

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。

【讨论】:

  • 这也有一个优点,它适用于不适合作为密集数组放入内存的稀疏数组。
【解决方案4】:

如果您尝试将每一行归一化,使其大小为 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]])

验证:

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

【讨论】:

  • Axis 似乎不是 np.linalg.norm 的参数(不再是?)。
  • 值得注意的是,这对应于 l2 范数(其中总和为 1 的行对应于 l1 范数)
【解决方案5】:

这似乎也有效

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

【讨论】:

    【解决方案6】:

    或者使用 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 的每个向量都有一个单位范数。

    【讨论】:

      【解决方案7】:

      你也可以使用矩阵转置:

      (a.T / row_sums).T
      

      【讨论】:

        【解决方案8】:

        我认为您可以通过以下方式将行元素的总和标准化为 1: new_matrix = a / a.sum(axis=1, keepdims=1)。 并且可以使用new_matrix = a / a.sum(axis=0, keepdims=1) 完成列规范化。希望这会有所帮助。

        【讨论】:

          【解决方案9】:
          normed_matrix = normalize(input_data, axis=1, norm='l1')
          print(normed_matrix)
          

          其中 input_data 是二维数组的名称

          【讨论】:

            【解决方案10】:

            您可以使用内置的 numpy 函数: np.linalg.norm(a, axis = 1, keepdims = True)

            【讨论】:

              【解决方案11】:

              这是使用reshape的另一种可能的方式:

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

              【讨论】:

                【解决方案12】:

                我们可以通过与主对角线是行和的倒数的对角矩阵进行预乘来达到相同的效果。

                A = np.diag(A.sum(1)**-1) @ A
                

                【讨论】:

                  猜你喜欢
                  • 2016-05-16
                  • 1970-01-01
                  • 2015-06-22
                  • 2017-07-16
                  • 2014-06-28
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2019-08-09
                  相关资源
                  最近更新 更多