Поиск в Numpy

Oct 01 2020

Я отсортировал число по возрастанию, если вы делаете abs (arr) в приведенном ниже коде, я пытаюсь найти индекс, в котором знак изменился с отрицательного на положительный. Написал этот код ниже, но по некоторым причинам я считаю, что мы можем улучшить его или оптимизировать. Любые советы и рекомендации?

import numpy as np
arr = np.array([-1,-2,-3, 4, 5, 6])
_cut_index_1 = np.where(arr > 0)[0][0]
_cut_index_2 = np.where(arr < 0)[0][-1]
arr[_cut_index_1] # output:   4
arr[_cut_index_2] # output:  -3

Ответы

4 Juho Oct 03 2020 at 00:45

Ваше текущее решение выполняет два прохода по входному массиву (два вызова np.where), что, как указано, кажется расточительным. Одним из простых способов решения проблемы является использование np.argmax, которое займет линейное время:

import numpy as np
arr = np.array([-1, -2, -3, 4, 5, 6])
np.argmax(arr > 0) # Return (index) 3

На этом этапе, если мы можем предположить (как вы, кажется, подразумеваете), что существует единственная интересующая позиция (и/или что нас интересует только первая, читаем слева направо), мы закончили: просто уменьшите единицу из ответ, и у вас есть другая точка отсечки (но проверьте, находимся ли мы в угловом случае, чтобы не возвращать недействительный индекс).

Но на самом деле, если вы можете с уверенностью предположить, что ввод отсортирован, вы можете избежать линейного сканирования и даже не читать весь ввод. Для этого вы можете выполнить бинарный поиск с помощью searchsorted . Теоретически это быстрее (т. е. логарифмическое, а не линейное в худшем случае), но на практике это будет зависеть от размера массива. То есть для достаточно маленьких массивов линейное сканирование будет быстрее из-за локальности кеша (или, по крайней мере, так должно быть по модулю ваших аппаратных данных).