l.index(x)
возвращает наименьшее значение i , такое что i является индексом первого появления x в списке.
Можно смело предположить, что функция index()
в Python реализована так, что она останавливается после нахождения первого совпадения, и это приводит к оптимальной средней производительности.
Для поиска остановки элемента после первого совпадения в массиве NumPy используйте итератор ( ndenumerate ).
In [67]: l=range(100)
In [68]: l.index(2)
Out[68]: 2
Массив NumPy:
In [69]: a = np.arange(100)
In [70]: next((idx for idx, val in np.ndenumerate(a) if val==2))
Out[70]: (2L,)
Обратите внимание, что оба метода index()
и next
возвращают ошибку, если элемент не найден. С next
можно использовать второй аргумент для возврата специального значения в случае, если элемент не найден, например,
In [77]: next((idx for idx, val in np.ndenumerate(a) if val==400),None)
В NumPy есть и другие функции (argmax
, where
и nonzero
), которые можно использовать для поиска элемента в массиве, но у всех них есть недостаток - проходить весь массив в поисках все вхождений, поэтому не оптимизированы для поиска первого элемента. Также обратите внимание, что where
и nonzero
возвращают массивы, поэтому вам нужно выбрать первый элемент, чтобы получить индекс.
In [71]: np.argmax(a==2)
Out[71]: 2
In [72]: np.where(a==2)
Out[72]: (array([2], dtype=int64),)
In [73]: np.nonzero(a==2)
Out[73]: (array([2], dtype=int64),)
Сравнение времени
Просто проверяя, что для больших массивов решение с использованием итератора быстрее , когда искомый элемент находится в начале массива (с использованием %timeit
в оболочке IPython):
In [285]: a = np.arange(100000)
In [286]: %timeit next((idx for idx, val in np.ndenumerate(a) if val==0))
100000 loops, best of 3: 17.6 µs per loop
In [287]: %timeit np.argmax(a==0)
1000 loops, best of 3: 254 µs per loop
In [288]: %timeit np.where(a==0)[0][0]
1000 loops, best of 3: 314 µs per loop
Это открытая NumPy GitHub проблема .
См. Также: Numpy: быстрый поиск первого индекса значения