在检查浮点数之间的相等性时需要小心,并且通常应该考虑到容差,例如使用numpy.allcose。
问题1:使用“in”关键字检查特定浮点数的出现是否安全(或者是否有类似的关键字/函数用于此目的)?例子:
if myFloatNumber in myListOfFloats:
print('Found it!')
else:
print('Sorry, no luck.')
问题 2:如果不是,那么整洁的解决方案是什么?
在检查浮点数之间的相等性时需要小心,并且通常应该考虑到容差,例如使用numpy.allcose。
问题1:使用“in”关键字检查特定浮点数的出现是否安全(或者是否有类似的关键字/函数用于此目的)?例子:
if myFloatNumber in myListOfFloats:
print('Found it!')
else:
print('Sorry, no luck.')
问题 2:如果不是,那么整洁的解决方案是什么?
如果您不在同一个地方或使用完全相同的方程式计算您的浮点数,那么您可能会对这段代码产生误报(因为舍入错误)。例如:
>>> 0.1 + 0.2 in [0.6/2, 0.3] # We may want this to be True
False
在这种情况下,我们可以只使用一个自定义的 " in
" 函数来实现这一点(在这种情况下,使用它可能会更好/更快,numpy.isclose
而不是numpy.allclose
):
import numpy as np
def close_to_any(a, floats, **kwargs):
return np.any(np.isclose(a, floats, **kwargs))
文档中有一个重要说明:
警告 默认
atol
值不适用于比较远小于 1 的数字(请参阅注释)。[...] 如果预期值明显小于 1,则可能导致误报。
注释补充说,与'satol
相反,不为零。如果您在使用时需要自定义容差,请使用传递和/或向下传递给 numpy。最后,您现有的代码将转换为:math.isclose
abs_tol
close_to_any
kwargs
rtol
atol
if close_to_any(myFloatNumber, myListOfFloats):
print('Found it!')
else:
print('Sorry, no luck.')
或者你可以有一些选项close_to_any(myFloatNumber, myListOfFloats, atol=1e-12)
,注意这1e-12
是任意的,除非你有充分的理由,否则你不应该使用这个值。
回到我们在第一个示例中观察到的舍入误差,这将给出:
>>> close_to_any(0.1 + 0.2, [0.6/2, 0.3])
True
Q1:取决于您将如何实现这一点。但是正如其他人提到的那样,使用浮点数并不是一个好主意in
。
Q2:你们在性能方面有什么限制吗?会myListOfFloats
排序吗?
如果它是浮点值的排序列表,并且您需要尽可能快地执行此操作,则可以实现二进制搜索算法。
如果数据未排序,则根据您将要进行的查询数量与数据大小之间的比率,您可能希望对数据进行排序并使其保持排序。
如果您对性能和速度没有任何要求,可以使用以下示例作为基础:
def inrng(number1,number2,prec):
if(abs(number1-number2)<prec):
return True
else:
return False
precision=0.001
for i in myListOfFloats:
if(inrng(i,myInputNumber,precision)):
#do stuff