Я хотел бы:numpy.searchsorted для массива, содержащего numpy.nan
index = numpy.searchsorted(array([ 1., 2., 3., nan, 4., 5.]), 4.2, side='left')
дать мне:
index = 4
Это работает до значения 3.9
, но не после nan
в массив.
Любые идеи?
Я хотел бы:numpy.searchsorted для массива, содержащего numpy.nan
index = numpy.searchsorted(array([ 1., 2., 3., nan, 4., 5.]), 4.2, side='left')
дать мне:
index = 4
Это работает до значения 3.9
, но не после nan
в массив.
Любые идеи?
Сортировка массива не сортируется, что необходимо для корректной работы searchsorted
. np.nan
появится последним в отсортированном массиве:
>>> np.sort([1., 2., 3., nan, 4., 5.])
array([ 1., 2., 3., 4., 5., nan])
Чтобы устранить эту проблему, вы можете передать в списке отсортированных показателей вашего массива, используя аргумент sorter
ключевого слова. Вы можете использовать np.argsort
, чтобы найти это:
>>> arg_sorted = np.argsort([1., 2., 3., nan, 4., 5.])
>>> np.searchsorted([1., 2., 3., nan, 4., 5.], 4.2, side='right', sorter=arg_sorted)
4
Редактировать: В соответствии с комментарием Хайма ниже, проходя sorter
аргумент будет означать функцию возвращает позицию в отсортированном массиве (не в неотсортированных один). Поскольку side='left'
указывает, что первый подходящий индекс должен быть возвращен, правильный индекс может быть лучше идентифицированный следующим методом с использованием np.searchsorted
:
>>> idx = np.searchsorted([1., 2., 3., nan, 4., 5.], 4.2, side='left')
>>> arg_sorted[idx]
4
Я не хватает репутации, чтобы добавить комментарий, поэтому я добавлю мои два цента в ответе.
У меня была аналогичная задача, и, насколько я понимаю, может возникнуть проблема с answer.
Для того, чтобы проиллюстрировать мою точку зрения, я расширить массив в вопрос с дополнительным элементом
a = np.array([1., 2., 3., np.nan, 4., 5., 6.])
и вызвать алгоритм argsort как перед
arg_sorted = np.argsort(a)
Кроме того, в дополнение к нахождению 4.2, я также рассмотрим 5.2. Затем выход предлагаемого решения является
for x in [4.2, 5.2]:
ind_tmp = np.searchsorted(a, x, side='left')
ind = arg_sorted[ind_tmp]
print('x={}, ind={}'.format(x, ind))
x=4.2, ind=4
x=5.2, ind=4
Где я считаю, что более правильный ответ найден с помощью sorter
аргумента, например, так
for x in [4.2, 5.2]:
ind_tmp = np.searchsorted(a, x, side='left', sorter=arg_sorted)
ind = arg_sorted[ind_tmp]
print('x={}, ind={}'.format(x, ind))
x=4.2, ind=5
x=5.2, ind=6
В этом случае 5,2 найдена в индексе одного выше 4.2, вопреки первоначальному ответу и более точно соответствует моему пониманию правильного решения.
Когда вы используете аргумент 'sorter', он возвращает позицию в отсортированном массиве, а не в несортированном. Если вы использовали 'side = 'left'', как это сделал OP, вы бы получили' 3' как возвращаемое, что правильно, но не то, что хотел OP. В этом случае, когда единственная проблема заключается в том, чтобы избавиться от nans, чтобы получить нужный индекс, вам придется делать 'arg_sorted [idx]', где 'idx' - это возврат из вашего вызова в' np.searchsorted'. – Jaime
Спасибо, что установил вещи прямо, Хайме. Я явно написал слишком много в спешке и пропущенных подробностях! Я отредактировал, чтобы включить ваш комментарий, и может редактировать дальше, если моя формулировка все еще отсутствует. –