numpy 배열을 내림차순으로 효율적으로 정렬 하시겠습니까?


121

이 특정 질문이 이전에 묻지 않은 것에 놀랐지 만 실제로 .NET 문서에서 찾지 못했습니다 np.sort.

정수를 보유하는 임의의 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])

하지만 솔루션을 내림차순 으로 정렬하고 싶습니다 .

이제 저는 항상 할 수 있다는 것을 압니다.

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

하지만이 마지막 문장이 효율적 입니까? 오름차순으로 복사본을 만든 다음이 복사본을 뒤집어 결과를 역순으로 얻지 않습니까? 이것이 사실이라면 효율적인 대안이 있습니까? np.sort정렬 작업에서 비교 부호를 변경하여 역순으로 항목을 가져 오는 매개 변수를 받아들이지 않는 것 같습니다 .

답변:


139

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

30
감사합니다.하지만 temp[::-1].sort()역순으로 정렬해야한다는 것을 어떻게 압니까 ?? 내가 읽는 방법은 원래 배열을 뒤집은 다음 정렬 (오름차순)하는 것입니다. 원래 배열을 뒤집은 다음 (무작위 순서로 제공됨) 오름차순으로 정렬하면 배열이 역순으로 반환되는 이유는 무엇입니까?
Amelio Vazquez-Reina

14
이 동작은 매우 직관적이지 않기 때문에 문서화되어 있습니까?
ebarr 2014

18
이것은 [::-1]단순히 numpy에게 배열을 실제로 재정렬하는 대신 배열을 역순으로 반복하도록 지시 하기 때문에 작동하는 것처럼 보입니다 . 따라서 내부 정렬이 발생하면 실제로 오름차순으로 정렬하고 비트를 이동하지만 역방향 반복 부분은 그대로 둡니다.
perimosocordiae 2014

45
a=np.array((...))관용구 a[::-1]는 아무것도 되 돌리지 않고 동일한 데이터에 대한 새로운보기 , 특히 미러보기 일뿐 입니다. 이 방법 a[::-1].sort() 은 미러링 된 이미지 에서 작동합니다. 즉, 미러링 된 이미지 에서 더 작은 항목을 왼쪽 으로 sort이동할 때 실제로 어레이 의 실제 메모리 블록에서 오른쪽 으로 이동한다는 것을 의미합니다 . 미러링 된 뷰는 오름차순으로 정렬되고 실제 데이터는 내림차순으로 정렬됩니다. 다른 동전과 거울로 집에서 혼자서 사용해보십시오! a
gboffi 2014

30
이것은 정말로 np.sort(temp,order='descending')이런 종류의 해킹을 요구하는 것보다 읽기 쉬운 매개 변수로 추가되어야합니다
Nathan

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

2
우수 답변 - 짧은 달콤한, 그리고에 대한 지식 axis있는에 np.sort적용된이 필요하다.
Luke Davis

2
이것은 s를 배열의 전면이 아닌 후면에 np.sort(temp)[::-1]배치한다는 점 과 다릅니다 nan. 그것이 좋든 나쁘 든 논쟁의 여지가 있습니다.
Ben

15

짧은 배열 np.argsort()의 경우 정렬 된 음수 배열의 인덱스를 찾아서 사용 하는 것이 좋습니다 . 이는 정렬 된 배열을 반대로하는 것보다 약간 빠릅니다.

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

a[np.argsort(-a)]아마도이 페이지의 다른 사람들에게 가장 좋은 방법 일 것입니다. -1 단계 반전이 없으며 생각할 마이너스 부호가 하나 적습니다.
Jarad

8

불행히도 복잡한 배열이 있으면 np.sort(temp)[::-1]제대로 작동합니다. 여기에 언급 된 다른 두 가지 방법은 효과적이지 않습니다.


@ anishtain4 : "복잡한 배열"이란 복소수의 배열을 의미 했습니까? 아니면 다른 종류의 복잡성을 가진 배열을 의미 했습니까 (그렇다면 pls가 어떤 종류의 복잡성을 지정하는지). 두 경우 모두 다른 방법이 실패 할 수있는 방법을 살펴봄으로써 답변에 대해 좀 더 자세히 설명 할 수 있다고 생각합니다. 감사.

@fountainhead 나는 복소수의 배열을 의미합니다. 오래된 질문이기 때문에 더 자세히 설명하기 위해 그때부터 내 테스트 케이스를 기억하지 못합니다.
anishtain4

8

치수에주의하십시오.

허락하다

x  # initial numpy array
I = np.argsort(x) or I = x.argsort() 
y = np.sort(x)    or y = x.sort()
z  # reverse sorted array

완전 반전

z = x[-I]
z = -np.sort(-x)
z = np.flip(y)
  • flip에서 변경되었으며 1.15이전 버전이 필요합니다 . 솔루션 : .1.14 axispip install --upgrade numpy

첫 번째 치수 반전

z = y[::-1]
z = np.flipud(y)
z = np.flip(y, axis=0)

두 번째 차원 반전

z = y[::-1, :]
z = np.fliplr(y)
z = np.flip(y, axis=1)

테스팅

100x10x10 어레이에서 1000 회 테스트.

Method       | Time (ms)
-------------+----------
y[::-1]      | 0.126659  # only in first dimension
-np.sort(-x) | 0.133152
np.flip(y)   | 0.121711
x[-I]        | 4.611778

x.sort()     | 0.024961
x.argsort()  | 0.041830
np.flip(x)   | 0.002026

이는 주로 argsort.

# Timing code
import time
import numpy as np


def timeit(fun, xs):
    t = time.time()
    for i in range(len(xs)):  # inline and map gave much worse results for x[-I], 5*t
        fun(xs[i])
    t = time.time() - t
    print(np.round(t,6))

I, N = 1000, (100, 10, 10)
xs = np.random.rand(I,*N)
timeit(lambda x: np.sort(x)[::-1], xs)
timeit(lambda x: -np.sort(-x), xs)
timeit(lambda x: np.flip(x.sort()), xs)
timeit(lambda x: x[-x.argsort()], xs)
timeit(lambda x: x.sort(), xs)
timeit(lambda x: x.argsort(), xs)
timeit(lambda x: np.flip(x), xs)

np.flip ()-super
Darius

6

안녕하세요 저는 2 차원 numpy 배열을 역 정렬하는 솔루션을 찾고 있었는데 작동하는 것을 찾을 수 없었지만 누군가가 같은 보트에있는 경우를 대비하여 업로드하는 솔루션을 우연히 발견했다고 생각합니다.

x=np.sort(array)
y=np.fliplr(x)

np.sort는 원하는대로 오름차순으로 정렬하지만 fliplr 명령은 행을 왼쪽에서 오른쪽으로 뒤집습니다! 작동하는 것 같습니다!

도움이 되었기를 바랍니다.

위의 -np.sort (-a)에 대한 제안과 비슷하다고 생각하지만 항상 작동하지는 않는다는 주석으로 미루 었습니다. 아마도 내 솔루션이 항상 작동하지는 않지만 몇 개의 어레이로 테스트했으며 괜찮은 것 같습니다.


1

배열을 먼저 정렬 (기본적으로 오름차순) 한 다음 np.flip () ( https://docs.scipy.org/doc/numpy/reference/generated/numpy.flip.html ) 을 적용 할 수 있습니다.

참고로 datetime 객체에서도 작동합니다.

예:

    x = np.array([2,3,1,0]) 
    x_sort_asc=np.sort(x) 
    print(x_sort_asc)

    >>> array([0, 1, 2, 3])

    x_sort_desc=np.flip(x_sort_asc) 
    print(x_sort_desc)

    >>> array([3,2,1,0])

배열에 NaN이있는 사람들의 경우, 다양한 제안 된 방법이 다른 결과를 생성합니다. 예를 들어, 만약 x = np.array([2,3,np.nan,1,0]) np.flip(np.sort(x))방법 수율 [2 1 0 3 유모] 동안 -np.sort(-x)접근 수율 [3. 2. 1. 0 유모].
Uwe Mayer

1

여기에 빠른 트릭이 있습니다.

In[3]: import numpy as np
In[4]: temp = np.random.randint(1,10, 10)
In[5]: temp
Out[5]: array([5, 4, 2, 9, 2, 3, 4, 7, 5, 8])

In[6]: sorted = np.sort(temp)
In[7]: rsorted = list(reversed(sorted))
In[8]: sorted
Out[8]: array([2, 2, 3, 4, 4, 5, 5, 7, 8, 9])

In[9]: rsorted
Out[9]: [9, 8, 7, 5, 5, 4, 4, 3, 2, 2]

-3

나는 이것을 사용하는 것이 좋습니다 ...

np.arange(start_index, end_index, intervals)[::-1]

예를 들면 :

np.arange(10, 20, 0.5)
np.arange(10, 20, 0.5)[::-1]

그런 다음 재 공격 :

[ 19.5,  19. ,  18.5,  18. ,  17.5,  17. ,  16.5,  16. ,  15.5,
    15. ,  14.5,  14. ,  13.5,  13. ,  12.5,  12. ,  11.5,  11. ,
    10.5,  10. ]

1
이것이 문제를 어떻게 해결합니까? 당신은 더 효율적인 방법으로 수행 될 수있는 완전히, 무관하고, 새로운 (내림차순) 배열을 만드는 것입니다 : np.arange(20-0.5, 10-0.5, -0.5). 그러나 그것은 다른 이야기이며 더 나쁜 가독성 때문에 논쟁의 여지가있을 수 있습니다. 입력 배열이 전혀 정렬되지 않았습니다
Daniel
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.