Как найти ближайшее значение, которое больше в массиве numpy?

Я хотел бы получить индекс ближайшего значения в массиве numpy, который больше моего значения поиска. Пример: findNearestAbove(np.array([0.,1.,1.4,2.]), 1.5) должен вернуть 3 (индекс 2.).

Я знаю, что я могу получить ближайший индекс с np.abs(a-value).argmin() , и я узнал, что min(a[np.where(a-value >= 0.)[0]]) возвращает требуемое значение массива. Следовательно, np.where(a == min(a[np.where(a-value >= 0.)[0]]))[0] , вероятно, даст мне желаемый индекс. Однако это выглядит довольно запутанным, и я боюсь, что он может сломаться в случае многомерных массивов. Любые предложения по улучшению этого?

Вот один из способов (я предполагаю, что ближе всего вы имеете в виду значение не местоположения)

 import numpy as np def find_nearest_above(my_array, target): diff = my_array - target mask = np.ma.less_equal(diff, 0) # We need to mask the negative differences and zero # since we are looking for values above if np.all(mask): return None # returns None if target is greater than any value masked_diff = np.ma.masked_array(diff, mask) return masked_diff.argmin() 

Результат:

 >>> find_nearest_above(np.array([0.,1.,1.4,2.]), 1.5) 3 >>> find_nearest_above(np.array([0.,1.,1.4,-2.]), -1.5) 0 >>> find_nearest_above(np.array([0., 1, 1.4, 2]), 3) >>> 

Я считаю, вы можете использовать np.searchsorted для этого:

 In [15]: np.searchsorted(a,[1.5,],side='right')[0] Out[15]: 3 

предполагая, что a находится в порядке возрастания.

Этот метод также не будет работать для многомерных массивов, но я не уверен точно, как этот случай использования будет работать с точки зрения ожидаемого результата. Если бы вы могли привести пример того, что вы себе представляете, я мог бы адаптировать это для этой цели.

Примечание : вы также можете использовать np.digitize для этой цели, хотя он выполняет линейный, а не двоичный поиск, поэтому для определенных размеров ввода он может быть намного медленнее, чем searchsorted и требует, чтобы a был монотонным:

 In [25]: np.digitize([1.5,], a, right=True)[0] Out[25]: 3 

Вот решение, которое очень хорошо работало для меня при поиске значения и индекса ближайшего, но большего, чем числа в массиве (никаких обещаний с точки зрения скорости и т. Д.):

 def findNearestGreaterThan(searchVal, inputData): diff = inputData - searchVal diff[diff<0] = np.inf idx = diff.argmin() return idx, inputData[idx] 

Он легко адаптируется для ближайшего, но меньше, чем:

 def findNearestLessThan(searchVal, inputData): diff = inputData - searchVal diff[diff>0] = -np.inf idx = diff.argmax() return idx, inputData[idx] 

Вот правильный способ сделать это:

 >>> def argfind(array, predicate): ... for i in xrange(array.shape[0]): ... if predicate(array[i]): ... return i ... return False ... >>> def find_nearest_above(array, value): ... return argfind(array, lambda x: x > value) ... >>> find_nearest_above(np.array([0.,1.,1.4,2.]), 1.5) > 3 

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