Поиск ближайшего значения и возврат индекса массива в Python

Я нашел этот пост: Python: поиск элемента в массиве

и речь идет о возврате индекса массива путем сопоставления значений.

С другой стороны, то, что я собираюсь сделать, похоже, но другое. Я хотел бы найти ближайшее значение для целевого значения. Например, я ищу 4.2, но я знаю, что в массиве нет 4.2, но я хочу вернуть индекс значения 4.1 вместо 4.4.

Какой был бы самый быстрый способ сделать это?

Я думаю о том, чтобы сделать это по-старому, как то, как я делал это с помощью Matlab, который использует массив A, где я хочу получить индекс от минус целевое значение и принять его абсолютное значение, а затем выбрать min. Что-то вроде этого:-

[~,idx] = min(abs(A - target)) 

Это код Matlab, но я новичок в Python, поэтому я думаю, есть ли быстрый способ сделать это в Python?

Большое вам спасибо за вашу помощь!

6 Solutions collect form web for “Поиск ближайшего значения и возврат индекса массива в Python”

Это похоже на использование bisect_left, но это позволит вам передать массив целей

 def find_closest(A, target): #A must be sorted idx = A.searchsorted(target) idx = np.clip(idx, 1, len(A)-1) left = A[idx-1] right = A[idx] idx -= target - left < right - target return idx 

Некоторое объяснение:

Сначала общий случай: idx = A.searchsorted(target) возвращает индекс для каждой target , так что target находится между A[index - 1] и A[index] . Я называю это left и right поэтому мы знаем, что left < target <= right . target - left < right - targetTrue (или 1), когда цель ближе к left и False (или 0), когда цель ближе к right .

Теперь особый случай: когда target меньше всех элементов A , idx = 0 . idx = np.clip(idx, 1, len(A)-1) заменяет все значения idx <1 на 1, поэтому idx=1 . В этом случае left = A[0] , right = A[1] и мы знаем, что target <= left <= right . Поэтому мы знаем, что target - left <= 0 и right - target >= 0 поэтому target - left < right - targetTrue если target == left == right и idx - True = 0 .

Существует еще один частный случай, если target больше всех элементов A В этом случае idx = A.searchsorted(target) и np.clip(idx, 1, len(A)-1) заменяет len(A) на len(A) - 1 поэтому idx=len(A) -1 и target - left < right - target заканчивается False поэтому idx возвращает len(A) -1 . Я позволю вам работать, хотя логика сама по себе.

Например:

 In [163]: A = np.arange(0, 20.) In [164]: target = np.array([-2, 100., 2., 2.4, 2.5, 2.6]) In [165]: find_closest(A, target) Out[165]: array([ 0, 19, 2, 2, 3, 3]) 

Соответствующий код Numpy почти то же самое, за исключением того, что вы используете numpy.argmin для поиска минимального индекса.

 idx = numpy.argmin(numpy.abs(A - target)) 

Протестировано и приурочено к двум решениям:

 idx = np.searchsorted(sw, sCut) 

а также

 idx = np.argmin(np.abs(sw - sCut)) 

для вычисления в дорогостоящем способе. время составило 113 секунд для вычисления со вторым решением и 132s для вычисления с первым .

Ну, прошло более 2 лет, и я нашел очень простую реализацию из этого URL-адреса: Найти ближайшее значение в массиве numpy

Реализация:

 def getnearpos(array,value): idx = (np.abs(array-value)).argmin() return idx 

Ура !!

Возможное решение:

 >>> a = [1.0, 3.2, -2.5, -3.1] >>> i = -1.5 >>> diff = [(abs(i - x),idx) for (idx,x) in enumerate(a)] >>> diff [(2.5, 0), (4.7, 1), (1.0, 2), (1.6, 3)] >>> diff.sort() >>> diff [(1.0, 2), (1.6, 3), (2.5, 0), (4.7, 1)] 

У вас будет индекс ближайшего значения в diff [0] [1]

 def finder(myList, target) diff = '' index = None for i,num in enumerate(myList): if abs(target - num) < diff: diff = abs(target - num) index = i return index 

Надеюсь это поможет

EDIT :

Если вам нужен один лайнер, вам может понравиться это лучше:

 min(L, key=lambda x: abs(target-x)) 
  • Итерирование вложенного списка наизнанку
  • Может ли от __future__ импортировать ... гарантировать совместимость Python 2 и 3?
  • Добавление лет в python
  • Как принимать входные данные как для типов int, так и для float?
  • Являются ли перечисления синтаксического сахара для `list (generator expression)` в Python 3?
  • Python Itertools.Permutations ()
  • Установить союз в пандах
  • Перемещение спрайта на другую сторону при удалении спрайта с экрана Pygame
  • Слабая ссылка на метод класса Python
  • Python3 - reload () нельзя вызвать в объекте __import__?
  • Разница между кодировкой utf-8 и utf8 в Python 3.5
  • Python - лучший язык программирования в мире.