I need to check if a given float is close, within a given tolerance, to any float in an array of floats.
import numpy as np
# My float
a = 0.27
# T
How about using np.isclose?
>>> np.isclose(arr_f, a, atol=0.01).any()
True
np.isclose
compares two objects element-wise to see if the values are within a given tolerance (here specified by the keyword argument atol
which is the absolute difference between two elements). The function returns a boolean array.
If you're only interested in a True
/False
result, then this should work:
In [1]: (abs(arr_f - a) < t).any()
Out[1]: True
Explanation: abs(arr_f - a) < t
returns a boolean array on which any()
is invoked in order to find out whether any of its values is True
.
EDIT - Comparing this approach and the one suggested in the other answer reveals that this one is slightly faster:
In [37]: arr_f = np.arange(0.05, 0.75, 0.008)
In [38]: timeit (abs(arr_f - a) < t).any()
100000 loops, best of 3: 11.5 µs per loop
In [39]: timeit np.isclose(arr_f, a, atol=t).any()
10000 loops, best of 3: 44.7 µs per loop
In [40]: arr_f = np.arange(0.05, 1000000, 0.008)
In [41]: timeit (abs(arr_f - a) < t).any()
1 loops, best of 3: 646 ms per loop
In [42]: timeit np.isclose(arr_f, a, atol=t).any()
1 loops, best of 3: 802 ms per loop
An alternative solution that also returns the relevant indices is as follows:
In [5]: np.where(abs(arr_f - a) < t)[0]
Out[5]: array([27, 28])
This means that the values residing in indices 27 and 28 of arr_f
are within the desired range, and indeed:
In [9]: arr_f[27]
Out[9]: 0.26600000000000001
In [10]: arr_f[28]
Out[10]: 0.27400000000000002
Using this approach can also generate a True
/False
result:
In [11]: np.where(abs(arr_f - a) < t)[0].any()
Out[11]: True