2014-11-18 2 views
43

Я удивлен, что этот конкретный вопрос не задавался раньше, но я действительно не нашел его на SO или документации np.sort.Эффективная сортировка массива numpy в порядке убывания?

Скажем, у меня есть случайный NumPy массив, содержащий целые числа, например:

> temp = np.random.randint(1,10, 10)  
> temp 
array([2, 4, 7, 4, 2, 2, 7, 6, 4, 4]) 

Если сортировать его, я получаю по возрастанию Сортировать по умолчанию:

> np.sort(temp) 
array([2, 2, 2, 4, 4, 4, 4, 6, 7, 7]) 

, но я хочу, чтобы решение для сортировки in по убыванию заказать.

Теперь, я знаю, что всегда можно сделать:

reverse_order = np.sort(temp)[::-1] 

, но это последнее утверждение эффективным? Разве он не создает копию в порядке возрастания, а затем отменяет эту копию, чтобы получить результат в обратном порядке? Если это действительно так, есть ли эффективная альтернатива? Не похоже, что np.sort принимает параметры, чтобы изменить знак сравнения в операции сортировки, чтобы получить информацию в обратном порядке.

ответ

57

temp[::-1].sort() сортирует массив на месте, np.sort(temp)[::-1] создает новый массив.

In [25]: temp = np.random.randint(1,10, 10) 

In [26]: temp 
Out[26]: array([5, 2, 7, 4, 4, 2, 8, 6, 4, 4]) 

In [27]: id(temp) 
Out[27]: 139962713524944 

In [28]: temp[::-1].sort() 

In [29]: temp 
Out[29]: array([8, 7, 6, 5, 4, 4, 4, 4, 2, 2]) 

In [30]: id(temp) 
Out[30]: 139962713524944 
+5

Спасибо, но как 'temp [:: - 1] .sort()' знает, что он должен сортировать в обратном порядке? То, как я его читаю, это: отменить исходный массив, а затем отсортировать его (в порядке возрастания). Почему бы изменить исходный массив (входящий в случайный порядок), а затем отсортировать его в порядке возрастания, вернуть массив в обратном порядке? –

+5

Является ли это поведение документированным, так как оно довольно неинтуитивно. – ebarr

+0

Не то, что я видел, но '[:: - 1]' часто используется с 'argsort' –

5

Для коротких массивов я предлагаю использовать np.argsort() путем поиска индексов отсортированного negatived массива, который немного быстрее, чем реверсирования отсортированного массива:

In [37]: temp = np.random.randint(1,10, 10) 

In [38]: %timeit np.sort(temp)[::-1] 
100000 loops, best of 3: 4.65 µs per loop 

In [39]: %timeit temp[np.argsort(-temp)] 
100000 loops, best of 3: 3.91 µs per loop 
-1

К сожалению, когда у вас есть сложный массив, только np.sort(temp)[::-1] работает правильно. Два других метода, упомянутых здесь, неэффективны.

4
>>> a=np.array([5, 2, 7, 4, 4, 2, 8, 6, 4, 4]) 

>>> np.sort(a) 
array([2, 2, 4, 4, 4, 4, 5, 6, 7, 8]) 

>>> -np.sort(-a) 
array([8, 7, 6, 5, 4, 4, 4, 4, 2, 2]) 
Смежные вопросы