Вы не можете знать, является ли ваше текущее решение хорошим или нет, если вы не знаете, какие есть альтернативы.
Во-первых,
np.where(np.isin(arr, val))
Работает для любого общего случая.np.isin
выполняет линейный поиск по arr
для элементов в val
.
Вы также можете заменить np.where
на np.nonzero
, что немного быстрее для больших N.
Далее, есть
(arr[:, None] == val).argmax(0)
То есть очень быстро для малых размеров arr и val (N <100). </p>
Наконец, если arr
отсортировано, я рекомендую 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)
Проблема с (arr[:, None] == val).argmax(0)
заключается в выбросе памяти - сравнение транслируется, вводя очень, очень разреженную матрицу, которая расточительна при большом N (поэтому не используйте его для большихN).