2014-12-02 2 views

ответ

3

Сортировка массива не сортируется, что необходимо для корректной работы 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 
+1

Когда вы используете аргумент 'sorter', он возвращает позицию в отсортированном массиве, а не в несортированном. Если вы использовали 'side = 'left'', как это сделал OP, вы бы получили' 3' как возвращаемое, что правильно, но не то, что хотел OP. В этом случае, когда единственная проблема заключается в том, чтобы избавиться от nans, чтобы получить нужный индекс, вам придется делать 'arg_sorted [idx]', где 'idx' - это возврат из вашего вызова в' np.searchsorted'. – Jaime

+0

Спасибо, что установил вещи прямо, Хайме. Я явно написал слишком много в спешке и пропущенных подробностях! Я отредактировал, чтобы включить ваш комментарий, и может редактировать дальше, если моя формулировка все еще отсутствует. –

0

Я не хватает репутации, чтобы добавить комментарий, поэтому я добавлю мои два цента в ответе.

У меня была аналогичная задача, и, насколько я понимаю, может возникнуть проблема с 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, вопреки первоначальному ответу и более точно соответствует моему пониманию правильного решения.

Смежные вопросы