numpy argsort

2019. 5. 26. 21:34분석 Python/Numpy Tip

728x90

argsort를 이용해서 하나의 기준이 있을 때 다른 것도 쉽게 정렬할 수 있다!

 

만약 키와 나이가 쌍이 있다고 하자.

ages = np.random.randint(low=30, high=60, size=10)
heights = np.random.randint(low=150, high=210, size=10)
print(ages)
print(heights)
## ages : [56 53 52 54 42 53 39 37 50 57]
## heights : [189 182 158 204 187 168 155 169 206 153]

이것을 나이를 기준으로 height 도 같이 sort해보자!

이 방식은 zip(ages , heights) 보다 훨씬 빠르다고 합니다!!

 

sorter = np.argsort(ages)
print(sorter)
print(ages[sorter])
print(heights[sorter])


# sorter [7 6 4 8 2 1 5 3 0 9]
# arges[sorter]  [37 39 42 50 52 53 53 54 56 57]
# heghts[sorter] [169 155 187 206 158 182 168 204 189 153]

permutation 순서대로 만들기!

 

permutation = np.random.permutation(10)
original = np.array(list("abcdefghij"))


print(permutation)  # [4 1 9 0 2 5 3 6 8 7]
print(original)                 #  ['a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j']
print(original[permutation])    #  ['e' 'b' 'j' 'a' 'c' 'f' 'd' 'g' 'i' 'h']

inverse_permutation = np.argsort(permutation)
print(inverse_permutation)      #  [3 1 5 0 6 2 4 8 9 7]

a[b][c] = a[b[c]]
print(original[permutation][inverse_permutation])
print(original[permutation[inverse_permutation]])

## np.argsort를 사용하여 재정렬을 할 수 있습니다!!

['a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j']
['a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j']


## Even faster inverse permutation 더 빠르게!
앞에 방식대로 계산을 하게되면 O(n log(n)) 시간이 걸리는데, 
밑에 방식대로 하면 , O(n)!! 훨씬 줄어듭니다.

## 위에선 argsort를 이용하지만 여기선 그렇게 안해도 됨!
print(np.argsort(permutation))
inverse_permutation = np.empty(len(permutation), dtype=np.int)
inverse_permutation[permutation] = np.arange(len(permutation))
print(inverse_permutation)
permutation[inverse_permutation]

[3 1 4 6 0 5 7 9 8 2]
[3 1 4 6 0 5 7 9 8 2]
[3 1 4 6 0 5 7 9 8 2]
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

주어진 array에서 크기순서대로 index를 뽑기!

data = np.random.random(10)
print(data)
print(np.argsort(np.argsort(data)))

[0.99798769 0.85743436 0.25778128 0.07958487 0.86766335 
0.70481852 0.89788838 0.08425192 0.41760999 0.35630344]

[9 6 2 0 7 5 8 1 4 3]

## 훨씬 쉽고 직관적이고 빠른 방법
from scipy.stats import rankdata
rankdata(data) - 1
array([9., 6., 2., 0., 7., 5., 8., 1., 4., 3.])

 

728x90

'분석 Python > Numpy Tip' 카테고리의 다른 글

Incredibly Fast Random Sampling in Python - 리뷰  (0) 2019.06.14
numpy.unique, numpy.searchsorted  (0) 2019.05.26
Broadcasting, numpy.newaxis  (0) 2019.05.26
넘파이 좋은 팁이 많음!  (0) 2019.05.25
Numpy  (0) 2017.12.25