You can't know whether your current solution is good or not if you don't know what the alternatives are.
First,
np.where(np.isin(arr, val))
Works for any general case. np.isin
does a linear search over arr
for elements in val
.
You can also substitute np.where
with np.nonzero
, which is a bit faster for larger N.
Next, there is
(arr[:, None] == val).argmax(0)
Which is very fast for small sizes of arr and val (N < 100).
Finally, if arr
is sorted, I recommend np.searchsorted
.
np.searchsorted(arr, val)
arr = np.arange(100000)
val = np.random.choice(arr, 1000)
%timeit np.where(np.isin(arr, val))
%timeit np.nonzero(np.isin(arr, val))
%timeit (arr[:, None] == val).argmax(0)
%timeit np.searchsorted(arr, val)
8.3 ms ± 320 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
7.88 ms ± 791 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
861 ms ± 6.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
235 µs ± 31.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
The problem with (arr[:, None] == val).argmax(0)
is the memory blowout - the comparison is broadcasted, introducing a very, very sparse matrix that is wasteful when N is large (so don't use it for large N).