numpy二维数组划分精确丢失

时间:2017-04-26 08:19:51

标签: python arrays numpy

当numpy 2d阵列分裂时,我遇到了一些麻烦。 我有一个2D numpy数组A(shape =(N,N)),然后我将它除以row_sum(轴= 1)并获得2D数组B,但是当我计算出B的row_sum(axis = 1)时,在某些行中不等于一个,代码如下:  (python2.7.x)

from __future__ import division
import numpy as np

A = np.array([[x_11, x_12, ..., x_1N],
              [x_21, x_22, ..., x_2N],
              [...   ...   ...  ... ]
              [x_N1, x_N2, ..., x_NN]]) # x_ij are some np.float64 values
B = A / np.sum(A, axis=1, keepdims=True)

理论上的结果:

np.count_nonzero(np.sum(B, axis=1) != 1)
# it should be 0

现实结果:

np.count_nonzero(np.sum(B, axis=1) != 1)
# something bigger than 0

我相信原因是精确丢失,尽管我使用的是dtype = np.float64。因为在我的项目中,A 2D阵列(形状=(N,N),N> 8000),大多数值非常小(例如= 1.0)而其他值非常大(例如,= 2000)同一行。

我试过这个:添加遗失物

while np.count_nonzero(np.sum(B, axis=1) != 1) != 0
    losts = 1 - B
    B[:, i] += losts # the i may change by some conditions

尽管如此,它最终可以解决这个问题,但对我项目的下一步并不好。

有人能帮帮我吗?非常感谢!!!

1 个答案:

答案 0 :(得分:2)

使用浮动数字时,精度会有所下降,浮动数字很难与完全自然数匹配。

证明这一点的简单测试是:

>>> 0.1 + 0.2 == 0.3
False

这是因为0.1 + 0.2的浮点表示为0.30000000000000004

要解决此问题,您只需切换到np.isclosenp.allclose

import numpy as np

N = 100
A = np.random.randn(N, N)
B = A / np.sum(A, axis=1, keepdims=True) 

然后:

>>> np.count_nonzero(np.sum(B, axis=1) != 1)
79

,而

>>> np.allclose(np.sum(B, axis=1), 1)
True

简而言之,您的行已正确归一化,它们只是不将完全归为1。

来自文档np.isclose(a, b)相当于:

  

absolute(a - b) <= (atol + rtol * absolute(b))

使用atol = 1e-8rtol = 1e-5(默认情况下),这是比较两个浮点数代表相同数字(或至少约为)的正确方法