numpy`rint`怪异行为

时间:2017-10-22 17:56:21

标签: python python-3.x numpy

这个问题是关于numpy.rint,根据定义,它会舍入到最接近的整数。但是,以下代码会产生不一致的结果。

In [1]: import numpy as np
        for i in range(5, 105, 10):
            print(i, np.rint(i/10))
Out[1]: 5 0 # Should be 1
        15 2 # Correct
        25 2 # Should be 3
        35 4 # Correct
        45 4 # Should be 5
        55 6 # Correct
        65 6 # Should be 7
        ...

所以似乎有一种模式:如果在除以10之后,单位为偶数,则向下舍入数字,但如果单位为奇数,则向上舍入数字。但是,根据rounding rules,单位的位置无关紧要!

要么numpy应该使用“round half up”,也就是说,正好是一半,它会向上舍入到下一个整数,或者它应该使用“round half down”。它既不能同时做,又不​​一致。

通常情况下,我会用numpy为此打开一个错误报告,但我不确定这是否完全numpy是奇怪的,或者是python如何解释浮点数或者到期的一些基本怪癖到loss of precision from conversion to binary and back

请注意,numpy.round(i, 0)的行为也相同。

修复是在除法后添加一小部分10:numpy.rint(i/10 + 0.1),答案是正确的。

2 个答案:

答案 0 :(得分:5)

自从接近普遍采用IEEE 754标准以来,数字函数已经涌向“舍入一半甚至”舍入,其中的描述可以在您链接到的同一维基百科页面上找到,但是a bit down

此处基本转换期间的精度损失不是问题,因为在此范围内将整数转换为浮点数(C双精度)是精确的,并且商可以在二进制浮点中精确表示。

添加0.1不是一个理智的解决方法。例如,添加0.1到4.42,你得到4.52,它最多为5.0而不是正确的4.0。

答案 1 :(得分:1)

蒂姆·彼得斯的帖子正确地解释了你所看到的是在Python 3中向最近的偶数整数四舍五入。

如果你想让Python 3返回数字四舍五入到最接近的整数而不是最近的偶数整数使用

 numpy.floor(np.float(x)+0.5)

而不是numpy.rint(x)

例如:

for i in range(5,105,10):
   print(i,np.floor(np.float(i)/10+0.5))

打印

5 1.0
15 2.0
25 3.0
35 4.0
 ......
75 8.0
85 9.0
95 10.0