파이썬에서 정렬 된 배열의 인덱스를 얻는 방법
숫자 목록이 있습니다.
myList = [1, 2, 3, 100, 5]
이제이 목록을 정렬하면 얻을 수 [1, 2, 3, 5, 100]
있습니다. 내가 원하는 것은 정렬 된 순서대로 원래 목록의 요소 인덱스입니다. 즉 [0, 1, 2, 4, 3]
, 값과 인덱스를 모두 반환하는 ala MATLAB의 정렬 함수입니다.
numpy를 사용하는 경우 argsort () 함수를 사용할 수 있습니다.
>>> import numpy
>>> numpy.argsort(myList)
array([0, 1, 2, 4, 3])
http://docs.scipy.org/doc/numpy/reference/generated/numpy.argsort.html
배열 또는 목록을 정렬하는 인수를 반환합니다.
다음과 같은 것 :
>>> myList = [1, 2, 3, 100, 5]
>>> [i[0] for i in sorted(enumerate(myList), key=lambda x:x[1])]
[0, 1, 2, 4, 3]
enumerate(myList)
(색인, 값)의 튜플을 포함하는 목록을 제공합니다.
[(0, 1), (1, 2), (2, 3), (3, 100), (4, 5)]
목록을 전달 sorted
하고 정렬 키 (각 튜플의 두 번째 요소; 추출 대상)를 추출하는 함수를 지정 하여 목록을 정렬합니다 lambda
. 마지막으로, 정렬 된 각 요소 의 원래 색인은 [i[0] for i in ...]
목록 이해를 사용하여 추출됩니다 .
myList = [1, 2, 3, 100, 5]
sorted(range(len(myList)),key=myList.__getitem__)
[0, 1, 2, 4, 3]
대답 enumerate
은 훌륭하지만 개인적으로 값으로 정렬하는 데 사용되는 람다를 좋아하지 않습니다. 다음은 색인과 값을 반대로하여 정렬합니다. 따라서 먼저 값을 기준으로 정렬 한 다음 색인을 기준으로 정렬합니다.
sorted((e,i) for i,e in enumerate(myList))
로 대답을 업데이트 enumerate
하고 itemgetter
:
sorted(enumerate(a), key=lambda x: x[1])
# [(0, 1), (1, 2), (2, 3), (4, 5), (3, 100)]
목록을 함께 압축하십시오 : 튜플의 첫 번째 요소가 색인이고 두 번째 요소는 값입니다 (그런 다음 튜플의 두 번째 값을 사용하여 정렬하면 x[1]
x는 튜플입니다)
또는 모듈 itemgetter
에서 사용 operator
:
from operator import itemgetter
sorted(enumerate(a), key=itemgetter(1))
numpy를 사용하지 않으려면
sorted(range(len(seq)), key=seq.__getitem__)
여기에 표시된 것처럼 가장 빠릅니다 .
perfplot (내 프로젝트) 으로 이것 에 대한 빠른 성능 검사를 수행 했으며 numpy 이외의 다른 것을 추천하기가 어렵다는 것을 알았습니다 (로그 스케일 참고).
줄거리를 재현하는 코드 :
import perfplot
import numpy
def sorted_enumerate(seq):
return [i for (v, i) in sorted((v, i) for (i, v) in enumerate(seq))]
def sorted_enumerate_key(seq):
return [x for x, y in sorted(enumerate(seq), key=lambda x: x[1])]
def sorted_range(seq):
return sorted(range(len(seq)), key=seq.__getitem__)
def numpy_argsort(x):
return numpy.argsort(x)
perfplot.save(
"argsort.png",
setup=lambda n: numpy.random.rand(n),
kernels=[sorted_enumerate, sorted_enumerate_key, sorted_range, numpy_argsort],
n_range=[2 ** k for k in range(15)],
xlabel="len(x)",
logx=True,
logy=True,
)
다른 답변은 잘못되었습니다.
argsort
한 번만 실행 하는 것이 해결책이 아닙니다. 예를 들어, 다음 코드는
import numpy as np
x = [3,1,2]
np.argsort(x)
수율 array([1, 2, 0], dtype=int64)
우리가 원하는 것이 아니다.
대답은 argsort
두 번 실행해야합니다 .
import numpy as np
x = [3,1,2]
np.argsort(np.argsort(x))
array([2, 0, 1], dtype=int64)
예상대로 제공합니다 .
기본적으로 argsort
외부 라이브러리 (예 : NumPy)를 사용하려는 경우 또는 종속성없이 순수 파이썬을 유지하려는 경우 필요한 구현은에 따라 다릅니다.
스스로에게 물어보아야 할 질문은 다음과 같습니다.
- indices that would sort the array/list
- indices that the elements would have in the sorted array/list
Unfortunately the example in the question doesn't make it clear what is desired because both will give the same result:
>>> arr = np.array([1, 2, 3, 100, 5])
>>> np.argsort(np.argsort(arr))
array([0, 1, 2, 4, 3], dtype=int64)
>>> np.argsort(arr)
array([0, 1, 2, 4, 3], dtype=int64)
Choosing the argsort
implementation
If you have NumPy at your disposal you can simply use the function numpy.argsort
or method numpy.ndarray.argsort
.
An implementation without NumPy was mentioned in some other answers already, so I'll just recap the fastest solution according to the benchmark answer here
def argsort(l):
return sorted(range(len(l)), key=l.__getitem__)
Getting the indices that would sort the array/list
To get the indices that would sort the array/list you can simply call argsort
on the array or list. I'm using the NumPy versions here but the Python implementation should give the same results
>>> arr = np.array([3, 1, 2, 4])
>>> np.argsort(arr)
array([1, 2, 0, 3], dtype=int64)
The result contains the indices that are needed to get the sorted array.
Since the sorted array would be [1, 2, 3, 4]
the argsorted array contains the indices of these elements in the original.
- The smallest value is
1
and it is at index1
in the original so the first element of the result is1
. - The
2
is at index2
in the original so the second element of the result is2
. - The
3
is at index0
in the original so the third element of the result is0
. - The largest value
4
and it is at index3
in the original so the last element of the result is3
.
Getting the indices that the elements would have in the sorted array/list
In this case you would need to apply argsort
twice:
>>> arr = np.array([3, 1, 2, 4])
>>> np.argsort(np.argsort(arr))
array([2, 0, 1, 3], dtype=int64)
In this case :
- the first element of the original is
3
, which is the third largest value so it would have index2
in the sorted array/list so the first element is2
. - the second element of the original is
1
, which is the smallest value so it would have index0
in the sorted array/list so the second element is0
. - the third element of the original is
2
, which is the second-smallest value so it would have index1
in the sorted array/list so the third element is1
. - the fourth element of the original is
4
which is the largest value so it would have index3
in the sorted array/list so the last element is3
.
Import numpy as np
색인
S=[11,2,44,55,66,0,10,3,33]
r=np.argsort(S)
[output]=array([5, 1, 7, 6, 0, 8, 2, 3, 4])
argsort S의 인덱스를 정렬 된 순서로 반환
가치를 위해
np.sort(S)
[output]=array([ 0, 2, 3, 10, 11, 33, 44, 55, 66])
0에서 n-1 사이의 다른 인덱스 배열을 만든 다음 이것을 원래 배열로 압축 한 다음 원래 값을 기준으로 정렬합니다
ar = [1,2,3,4,5]
new_ar = list(zip(ar,[i for i in range(len(ar))]))
new_ar.sort()
`
참고 URL : https://stackoverflow.com/questions/6422700/how-to-get-indices-of-a-sorted-array-in-python
'Programing' 카테고리의 다른 글
응용 프로그램 자동 빌드 버전 관리 (0) | 2020.05.24 |
---|---|
NSUserDefaults에 NSDate를 저장하는 가장 좋은 방법은 무엇입니까? (0) | 2020.05.24 |
부트 스트랩을 사용하여 양식에 오류 표시 (0) | 2020.05.24 |
Java에서 동기화 된 정적 메소드는 어떻게 작동합니까? (0) | 2020.05.24 |
Ruby on Rails에서 "Sun Oct 5th"와 같이 "th"접미사로 날짜를 어떻게 형식화합니까? (0) | 2020.05.24 |