检查特定的浮点值是否在Python / numpy的列表/数组中

时间:2019-03-19 10:42:20

标签: python numpy floating-point floating-point-comparison

在检查浮点数之间的相等性时需要格外小心,通常应考虑容忍度,例如使用numpy.allcose

问题1:使用“ in”关键字检查是否存在特定的浮点数是否安全(或者为此目的是否存在类似的关键字/功能)?示例:

if myFloatNumber in myListOfFloats:
  print('Found it!')
else:
  print('Sorry, no luck.')

问题2:如果没有,什么是一个整洁的解决方案?

2 个答案:

答案 0 :(得分:4)

如果您不在同一位置或使用完全相同的方程式计算浮点数,则此代码可能会产生假负数(由于舍入误差)。例如:

>>> 0.1 + 0.2 in [0.6/2, 0.3]  # We may want this to be True
False

在这种情况下,我们只能使用一个自定义的“ in”函数,该函数实际上将成为现实(在这种情况下,使用numpy.isclose而不是{{3}可能更好/更快。 }):

import numpy as np 

def close_to_any(a, floats, **kwargs):
  return np.any(np.isclose(a, floats, **kwargs))

文档中有一个重要说明:

  

警告   默认的atol不适用于比较比1小得多的数字(请参阅注释)。   [...]   如果期望值明显小于1,则可能导致误报。

该注释还补充说明,atolnumpy.allcloseabs_tol不为零。如果在使用close_to_any时需要自定义公差,请使用kwargsrtol和/或atol向下传递给numpy。最后,您现有的代码将转换为:

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

答案 1 :(得分:1)

第一季度: 取决于您将如何实现此目标。但是正如其他使用float提到的那样,使用in运算符并不是一个好主意。

第二季度: 您对性能有任何限制吗? myListOfFloats会被排序吗?

如果它是浮点值的排序列表,并且需要尽快执行,则可以实现binary search算法。

如果未对数据进行排序,则取决于要进行的查询数量与数据大小之间的比率,您可能希望对数据进行排序并保持排序。

如果您对性能和速度没有任何要求,则可以使用以下示例作为基础:

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