小于或等于numpy浮点运算符?

时间:2019-05-02 02:32:08

标签: python numpy floating-point

我意识到np.islcose()函数可用于安全地检查浮点数是否相等。不过,令我感到困扰的是,使用标准的<=运算符会得到各种各样的结果。例如:

circle = Circle(5)
print(circle.area())
#78.53981633974483
cylinder = Cylinder(5, 3)
print(cylinder.volume())
#235.61944901923448

给我

add_to = 0.05
value64 = np.float64(0.3) + add_to*4
value32 = np.float32(0.3) + add_to*4
threshold = 0.5
print('is close?')
print(np.isclose(value64, threshold))
print(np.isclose(value32, threshold))
print('is less than or equals to?')
print(value64 <= threshold)
print(value32 <= threshold)

有人对此有一个明智的解决方法吗?我认为一个选择可能是让python比较运算符重载numpy浮点数,并且(在该函数内)将两个浮点数舍入到它们的小数点后第8位。但这是在速度有些重要并且感觉有点麻烦的情况下进行的。

在此先感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

根据此Difference between Python float and numpy float32,python在查看np.float32np.float64的方式上有区别。如果您实际检查value64value32的中间值,则会看到:

value32 = 0.5000000119209289
value64 = 0.5

这说明了为什么print(value32 <= threshold)的计算结果为假。由于二进制错误,我怀疑四舍五入到小数点后八位是否安全,因为使用value32时,您将拥有0.50000001

您还应该考虑将数字四舍五入的时间绝对是很小的,并且在

的情况下仍必须使用
np.float64(0.1) + np.float64(0.2)

,因为它的值为0.30000000000000004,因此使用>=<=时会出错。如果您使用decimal库,也会发生此错误。简而言之,有些数字确实无法避免发生某种错误。我知道绕过这个问题的唯一方法就是四舍五入。

我尝试测试一堆带有舍入和不带有舍入的组合,并且它是如此之快,以至于我无法记录10000次迭代中的时间差,因此除非您交易股票或训练神经网络数周,否则我不会认为四舍五入是您无需担心的事情。

如果您担心将数字四舍五入的随意性,我会在一个有效数字之后搜索一个0长于4的字符串,然后从中删除。

答案 1 :(得分:0)

您可以定义将<>isclose组合在一起的函数。

def approx_lte(x, y):
    return x <= y or np.isclose(x, y)
def approx_gte(x, y):
    return x => y or np.isclose(x, y)

它们类似于<=>=,除了它们还使用np.isclose()来测试是否相等。