'Find the first and last element of a NumPy array larger than a threshold
I need to find the first and the last element of a numpy.ndarray
which are above a specified threshold. I found the following solution, which works, but it looks a bit convoluted. Is there a simpler/more Pythonic way?
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(1)
test = np.random.uniform(0, 1, 100)
above_threshold = test > 0.95
plt.plot(above_threshold)
indices = np.nonzero(above_threshold)
imin = np.min(indices)
imax = np.max(indices)
print(imin, imax)
Solution 1:[1]
You could just access the first/last elements
s = np.flatnonzero(test > 0.95)
imin, imax = s[0], s[-1]
Solution 2:[2]
A fancy index on the first element of the tuple returned by nonzero
is all you need:
imin, imax = np.nonzero(above_threshold)[0][[0,-1]]
In [465]: imin
Out[465]: 21
In [466]: imax
Out[466]: 87
Output of the above using this sample:
In [454]: test
Out[454]:
array([4.17022005e-01, 7.20324493e-01, 1.14374817e-04, 3.02332573e-01,
1.46755891e-01, 9.23385948e-02, 1.86260211e-01, 3.45560727e-01,
3.96767474e-01, 5.38816734e-01, 4.19194514e-01, 6.85219500e-01,
2.04452250e-01, 8.78117436e-01, 2.73875932e-02, 6.70467510e-01,
4.17304802e-01, 5.58689828e-01, 1.40386939e-01, 1.98101489e-01,
8.00744569e-01, 9.68261576e-01, 3.13424178e-01, 6.92322616e-01,
8.76389152e-01, 8.94606664e-01, 8.50442114e-02, 3.90547832e-02,
1.69830420e-01, 8.78142503e-01, 9.83468338e-02, 4.21107625e-01,
9.57889530e-01, 5.33165285e-01, 6.91877114e-01, 3.15515631e-01,
6.86500928e-01, 8.34625672e-01, 1.82882773e-02, 7.50144315e-01,
9.88861089e-01, 7.48165654e-01, 2.80443992e-01, 7.89279328e-01,
1.03226007e-01, 4.47893526e-01, 9.08595503e-01, 2.93614148e-01,
2.87775339e-01, 1.30028572e-01, 1.93669579e-02, 6.78835533e-01,
2.11628116e-01, 2.65546659e-01, 4.91573159e-01, 5.33625451e-02,
5.74117605e-01, 1.46728575e-01, 5.89305537e-01, 6.99758360e-01,
1.02334429e-01, 4.14055988e-01, 6.94400158e-01, 4.14179270e-01,
4.99534589e-02, 5.35896406e-01, 6.63794645e-01, 5.14889112e-01,
9.44594756e-01, 5.86555041e-01, 9.03401915e-01, 1.37474704e-01,
1.39276347e-01, 8.07391289e-01, 3.97676837e-01, 1.65354197e-01,
9.27508580e-01, 3.47765860e-01, 7.50812103e-01, 7.25997985e-01,
8.83306091e-01, 6.23672207e-01, 7.50942434e-01, 3.48898342e-01,
2.69927892e-01, 8.95886218e-01, 4.28091190e-01, 9.64840047e-01,
6.63441498e-01, 6.21695720e-01, 1.14745973e-01, 9.49489259e-01,
4.49912133e-01, 5.78389614e-01, 4.08136803e-01, 2.37026980e-01,
9.03379521e-01, 5.73679487e-01, 2.87032703e-03, 6.17144914e-01])
Solution 3:[3]
Returns 21 and 87.
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(1)
test = np.random.uniform(0, 1, 100)
imin, imax = np.ma.flatnotmasked_edges(np.ma.masked_array(test, test <= 0.95))
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | rafaelc |
Solution 2 | Peter Mortensen |
Solution 3 |