Нахождение ближайшего значения и возврат индекса массива в Python - PullRequest
33 голосов
/ 18 января 2012

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

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

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

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

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

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

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

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

Ответы [ 6 ]

32 голосов
/ 19 января 2012

Это похоже на использование 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 - target равно True (или 1), когда цель ближе к left и False (или 0), когда цель ближе к right.

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

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

idx = numpy.argmin(numpy.abs(A - target))
6 голосов
/ 20 ноября 2014

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

Реализация:

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

Ура !!

4 голосов
/ 30 августа 2013

Протестировано и рассчитано два решения:

idx = np.searchsorted(sw, sCut)

и

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

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

2 голосов
/ 18 января 2012

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

>>> 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]

0 голосов
/ 18 января 2012
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

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

РЕДАКТИРОВАТЬ :

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

min(L, key=lambda x: abs(target-x))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...