使用numpy查找数组中第一个元素的索引,该索引接近float的容差范围内

时间:2016-12-07 16:38:30

标签: python arrays numpy

我需要找到数组中 first 元素的索引,该索引接近给定容差范围内的浮点数。

我可以使用for block执行此操作:

import numpy as np

# Define array of floats
a = np.random.uniform(0., 10., 10.)

# Float to search, and tolerance.
val, tol = 6.87, 0.1

for i, _ in enumerate(a):
    if np.isclose(_, val, tol):
        print('Index is: {}'.format(i))
        break

但我想知道是否有使用numpy功能的单线解决方案。

请注意,我对第一个元素的索引感兴趣,该元素接近val,无论在a下面可能有更近的元素数组。我发现的解决方案对 值的索引感兴趣,无论它位于数组中的哪个位置。

4 个答案:

答案 0 :(得分:6)

这是一个单行:

Index = next(i for i, _ in enumerate(a) if np.isclose(_, val, tol))

这是什么?

括号中的代码是生成器表达式next返回(您猜对了!)下一个(在这种情况下,第一个)值发电机会产生。如果没有下一个值,则会引发StopIteration异常。

优点

  1. 它不需要占用内存,因为它不需要计算所有可能的值并存储它们。
  2. 它很快,因为如果已找到所需的值,它不会继续循环遍历数组。
  3. 如果找不到任何值,它将引发异常。
  4. 可以很容易地变成单行功能:

    FirstIndex = lambda a, val, tol: next(i for i, _ in enumerate(a) if np.isclose(_, val, tol))
    
    i = FirstIndex(a, val, tol) # call it
    

答案 1 :(得分:4)

这是一个矢量化的单行 -

(np.abs(a - val) <= tol).argmax()

逐步运行示例 -

In [57]: a
Out[57]: array([5, 3, 9, 6, 8, 3, 5, 1])

In [58]: val = 2

In [59]: tol = 2

In [60]: (np.abs(a - val) < tol) # Many might satisfy
Out[60]: array([False,True,False,False,False,True,False,True], dtype=bool)

In [61]: (np.abs(a - val) <= tol).argmax() # Choose the first one with argmax
Out[61]: 1

答案 2 :(得分:3)

您可以使用numpy.where

np.where(np.isclose(a, val, tol))

刚刚获得where返回的最低索引(即第一个结果)。

希望这有帮助。

答案 3 :(得分:0)

加油!以上都不是可靠的。如果没有最接近的值,即使Divakar的答案也会失败,您也会得到Index = 0,这是一个错误。在这种情况下,它可能应该返回“ None”。因此,至少没有一个衬套是不可能的。最初的问题并不恰当。您需要考虑:“ ...如果公差内没有这样的接近值怎么办?”然后给出在这种情况下的操作规范。

i_array = np.where(np.isclose(a, val, tol))

足够公平,但是随后仍然需要处理一个空结果。因此,我想说一线是笨重的,至少两线是可取的:

i_array = np.where(np.isclose(a, val, tol))
my_i = None if (len(i_array[0])==0) else int(i_array[0])