Numpy argsort-무엇을하고 있습니까?


123

numpy가이 결과를 제공하는 이유 :

x = numpy.array([1.48,1.41,0.0,0.1])
print x.argsort()

>[2 3 1 0]

내가 이것을 기대할 때 :

[3 2 0 1]

분명히 기능에 대한 이해가 부족합니다.


6
[3 2 0 1]정답 이라고 생각 했 습니까?
zwol

9
나는 방금 출력에 대해 역으로 이해했습니다. 즉, x의 첫 번째 요소를 취하면 정렬 된 배열의 위치 3에 있어야합니다.
user1276273 jul.

26
생각의 당신의 방법은 완전히 내가 정확히 같은 질문을했다, 의미가
adrienlucca.wordpress.com

2
[3 2 0 1]-이것은 값의 순위를 매기는 것이며, 실제 지수를 얻지 못합니다.
Lahiru Karunaratne

출력은 정렬 된 배열에서 생각하는 동안 원래 배열의 위치를 ​​나타냄을 기억하십시오. 즉, output [0]은 원래 입력 배열에서 가장 작은 요소가있는 인덱스이고 가장 큰 요소는 output [-1]입니다.
lincr

답변:


143

문서 에 따르면

배열을 정렬 할 인덱스를 반환합니다.

  • 2의 색인입니다 0.0.
  • 3의 색인입니다 0.1.
  • 1의 색인입니다 1.41.
  • 0의 색인입니다 1.48.

12
a = x.argsort()인쇄 x[a]우리가 얻을 것이다,array([ 0. , 0.1 , 1.41, 1.48])
Belter

39

[2, 3, 1, 0] 가장 작은 요소가 인덱스 2, 인덱스 3, 인덱스 1, 인덱스 0에 있음을 나타냅니다.

가 있습니다 여러 가지 방법으로 당신이 찾고있는 결과를 얻기는 :

import numpy as np
import scipy.stats as stats

def using_indexed_assignment(x):
    "https://stackoverflow.com/a/5284703/190597 (Sven Marnach)"
    result = np.empty(len(x), dtype=int)
    temp = x.argsort()
    result[temp] = np.arange(len(x))
    return result

def using_rankdata(x):
    return stats.rankdata(x)-1

def using_argsort_twice(x):
    "https://stackoverflow.com/a/6266510/190597 (k.rooijers)"
    return np.argsort(np.argsort(x))

def using_digitize(x):
    unique_vals, index = np.unique(x, return_inverse=True)
    return np.digitize(x, bins=unique_vals) - 1

예를 들면

In [72]: x = np.array([1.48,1.41,0.0,0.1])

In [73]: using_indexed_assignment(x)
Out[73]: array([3, 2, 0, 1])

이는 모두 동일한 결과를 생성하는지 확인합니다.

x = np.random.random(10**5)
expected = using_indexed_assignment(x)
for func in (using_argsort_twice, using_digitize, using_rankdata):
    assert np.allclose(expected, func(x))

이러한 IPython %timeit벤치 마크는 대규모 어레이 using_indexed_assignment에 대해 가장 빠르다고 제안합니다 .

In [50]: x = np.random.random(10**5)
In [66]: %timeit using_indexed_assignment(x)
100 loops, best of 3: 9.32 ms per loop

In [70]: %timeit using_rankdata(x)
100 loops, best of 3: 10.6 ms per loop

In [56]: %timeit using_argsort_twice(x)
100 loops, best of 3: 16.2 ms per loop

In [59]: %timeit using_digitize(x)
10 loops, best of 3: 27 ms per loop

작은 배열의 경우 using_argsort_twice 경우 더 빠를 수 있습니다.

In [78]: x = np.random.random(10**2)

In [81]: %timeit using_argsort_twice(x)
100000 loops, best of 3: 3.45 µs per loop

In [79]: %timeit using_indexed_assignment(x)
100000 loops, best of 3: 4.78 µs per loop

In [80]: %timeit using_rankdata(x)
100000 loops, best of 3: 19 µs per loop

In [82]: %timeit using_digitize(x)
10000 loops, best of 3: 26.2 µs per loop

또한 stats.rankdata동일한 값의 요소를 처리하는 방법을 더 잘 제어 할 수 있습니다.


1
argsort ()를 두 번 적용하면 순위가 나오는 이유에 대한 설명을 추가 할 수 있습니까?
Phani

1
@Phani : argsort정렬 된 배열의 인덱스를 반환합니다. 정렬 된 인덱스의 인덱스가 순위입니다. 이것이 argsort반환 하는 두 번째 호출 입니다.
unutbu

2
첫 번째 argsort는 순열을 반환합니다 (데이터에 적용하면 정렬 됨). argsort가 (이 또는 임의의) 순열에 적용되면 역 순열을 반환합니다 (두 순열이 어느 순서로든 서로 적용되는 경우 결과는 Identity). 정렬 된 데이터 배열에 적용되는 경우 두 번째 순열은 정렬되지 않은 데이터 배열을 생성합니다. 즉, 순위입니다.
Alex C

1
마음을 날려. 드디어 이해했습니다! 콘텐츠가 정렬 된 순서로 원래 배열의 인덱스 인 배열을 반환합니다.
Jose A

3

설명서를 말한다argsort :

배열을 정렬 할 인덱스를 반환합니다.

즉, argsort의 첫 번째 요소는 먼저 정렬해야하는 요소의 색인이고 두 번째 요소는 두 번째 여야하는 요소의 색인 등입니다.

원하는 것은에서 제공하는 값의 순위 순서입니다 scipy.stats.rankdata. 계급에 동점이 있으면 어떻게해야하는지 생각해야합니다.


3

numpy.argsort (a, axis = -1, 종류 = 'quicksort', order = None)

배열을 정렬 할 인덱스를 반환합니다.

kind 키워드로 지정된 알고리즘을 사용하여 지정된 축을 따라 간접 정렬을 수행합니다. 지정된 축을 따라 정렬 된 순서로 인덱스 데이터와 동일한 모양의 인덱스 배열을 반환합니다.

다음과 같은 값 목록을 갖는 파이썬의 한 예를 고려하십시오.

listExample  = [0 , 2, 2456,  2000, 5000, 0, 1]

이제 우리는 argsort 함수를 사용합니다.

import numpy as np
list(np.argsort(listExample))

출력은

[0, 5, 6, 1, 3, 2, 4]

이것은 listExample에있는 값의 인덱스 목록입니다. 이러한 인덱스를 각 값에 매핑하면 다음과 같은 결과를 얻을 수 있습니다.

[0, 0, 1, 2, 2000, 2456, 5000]

(예를 들어 목록 / 배열을 정렬하고 싶지만 list.sort () 함수를 사용하고 싶지 않은 경우 (즉, 목록에서 실제 값의 순서를 변경하지 않고)이 함수를 사용할 수 있습니다. 함수.)

자세한 내용은 다음 링크를 참조하십시오. https://docs.scipy.org/doc/numpy-1.15.0/reference/generated/numpy.argsort.html


1

입력 :
import numpy as np
x = np.array ([1.48,1.41,0.0,0.1])
x.argsort (). argsort ()

출력 :
array ([3, 2, 0, 1])


1
이 코드 조각이 해결책이 될 수 있지만 설명을 포함하면 게시물의 품질을 향상시키는 데 도움이됩니다. 앞으로 독자를 위해 질문에 답하고 있으며, 해당 사용자는 코드 제안 이유를 모를 수 있습니다.
peacetype


0

np.argsort는 '종류'(정렬 알고리즘 유형 지정)로 지정된 정렬 배열의 색인을 리턴합니다. 그러나 목록이 np.argmax와 함께 사용되면 목록에서 가장 큰 요소의 인덱스를 반환합니다. np.sort는 주어진 배열, list를 정렬합니다.


0

OP의 원래 이해와 코드를 사용한 실제 구현을 직접 대조하고 싶습니다.

numpy.argsort 1D 배열의 경우 다음과 같이 정의됩니다.

x[x.argsort()] == numpy.sort(x) # this will be an array of True's

OP는 원래 1D 배열에 대해 다음과 같이 정의되었다고 생각했습니다.

x == numpy.sort(x)[x.argsort()] # this will not be True

참고 : 이 코드는 일반적인 경우에는 작동하지 않습니다 (1D에서만 작동 함).이 답변은 순전히 설명을위한 것입니다.


x[x.argsort()]과 반드시 ​​동일하지는 않습니다 np.sort(x). 사실, 반드시 같은 모양 일 필요는 없습니다. 2D 배열로 이것을 시도하십시오. 이것은 1D 배열에서만 작동합니다.
Nathan

불필요하게 현학적 인 것 같습니다. 문제는 1D 배열에 관한 것입니다. 이것은 사용할 리터럴 코드가 아니라 차이점이 무엇인지 이해하기위한 방법입니다. 또한 2D 배열이있는 경우 원하는 정렬 유형도 명확하지 않습니다. 글로벌 정렬을 원하십니까? 그렇지 않은 경우 어떤 축을 정렬해야합니까? 그럼에도 불구하고 나는 면책 조항을 추가했습니다.
Multihunter 2019 년

0

주어진 배열 인덱스에 따라 인덱스를 반환 [1.48,1.41,0.0,0.1]합니다. 즉 0.0, 인덱스 [2]의 첫 번째 요소입니다. 0.1index [3]의 두 번째 요소입니다. 1.41인덱스 [1]의 세 번째 요소입니다. 1.48index [0]의 네 번째 요소입니다. 산출:

[2,3,1,0]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.