在numpy中规范化列

时间:2014-02-12 13:30:10

标签: python numpy

问题:

如果我有一个2D numpy数组,如下所示:

[[1., 0., 1.]
 [1., 0., 2.]
 [2., 0., 1.]]

我希望将所有列标准化为总和为1,从而产生:

[[0.25, 0.33, 0.25]
 [0.25, 0.33, 0.50]
 [0.50, 0.33, 0.25]]

请注意,在列的总和为0的情况下,我希望它们如上所述均匀分布。它本质上只是缩放,但有特殊情况。

现有尝试

如果我保证所有列都加起来> 0那么我就可以这样做:

>>> x = np.array([[1,2,3],[4,5,6],[7,8,9]]) * 1.0

>>> x
array([[ 1.,  2.,  3.],
       [ 4.,  5.,  6.],
       [ 7.,  8.,  9.]])

>>> x / np.sum(x, axis=0)
array([[ 0.08333333,  0.13333333,  0.16666667],
       [ 0.33333333,  0.33333333,  0.33333333],
       [ 0.58333333,  0.53333333,  0.5       ]])

但是第一个示例失败了,因为您收到/0错误。

理想解决方案

如果存在可以扩展到第三维的一般解决方案,那将是理想的。上面运行的示例对于3D阵列完全相同,但在零情况下仍然失败。

>>> x = np.array([[[1,2,3],[4,5,6],[7,8,9]], [[10, 11, 12], [13, 14, 15], [16, 17, 18]]]) * 1.0

>>> x
array([[[  1.,   2.,   3.],
        [  4.,   5.,   6.],
        [  7.,   8.,   9.]],

       [[ 10.,  11.,  12.],
        [ 13.,  14.,  15.],
        [ 16.,  17.,  18.]]])

>>> x / np.sum(x, axis=0)
array([[[ 0.09090909,  0.15384615,  0.2       ],
        [ 0.23529412,  0.26315789,  0.28571429],
        [ 0.30434783,  0.32      ,  0.33333333]],

       [[ 0.90909091,  0.84615385,  0.8       ],
        [ 0.76470588,  0.73684211,  0.71428571],
        [ 0.69565217,  0.68      ,  0.66666667]]])

1 个答案:

答案 0 :(得分:6)

只需将全零列设置为任意非零值,然后继续执行:

>>> x = np.array([[1., 0., 1.],
...               [1., 0., 2.],
...               [2., 0., 1.]])
>>> x[:, np.all(x == 0, axis=0)] = 1
>>> x / np.sum(x, axis=0)
array([[ 0.25      ,  0.33333333,  0.25      ],
       [ 0.25      ,  0.33333333,  0.5       ],
       [ 0.5       ,  0.33333333,  0.25      ]])