Studio KimHippo :D

[Python / NumPy] 7.팬시 인덱싱, NumPy 정렬 본문

Python Study/NumPy

[Python / NumPy] 7.팬시 인덱싱, NumPy 정렬

김작은하마 2019. 7. 8. 16:15
# -*- coding : utf-8 -*-
import numpy as np

# NOTE: 팬시 인덱싱
# 팬시 인덱싱 : 단일 스칼라 대신 인덱스 배열을 반환
#             이로써 복잡한 배열 값의 하위 집합에 매우 빠르게 접근하여 수정가능
rand = np.random.RandomState(42)
x = rand.randint(100, size = 10)
x

# NOTE : 세 개의 다른 요소에 접근하고자 할 때
print([x[3], x[7], x[2]])

# NOTE : 인덱스의 단일 리스트나 배열을 전달
ind = [3, 7, 4]
print(x[ind])

# NOTE : 결과의 형상이 대상 배열의 형상이 아니라 인덱스 배열의 형상을 반영
ind = np.array([[3, 7],
                [4, 5]])
print(x[ind])

Out [1] :

array([51, 92, 14, 71, 60, 20, 82, 86, 74, 74])

 

Out [2] :

[71, 86, 14]
[71 86 60]

 

Out [3] :

[[71 86]
 [60 20]]

y = np.arange(12).reshape((3, 4))
y

row = np.array([0, 1, 2])
col = np.array([2, 1, 3])
print(y[row, col], '\n')
# output : [2  5 11]
# NOTE : 결과의 첫 번째 값은 y[0, 2], 두 번째 값은 y[1,1], 세 번째 값은 y[2, 3]

print(y[row[:,np.newaxis], col], '\n')
print(row[:, np.newaxis] * col)

# NOTE : 팬시 인덱싱을 사용하면 인덱싱 대상 배열의 형상이 아니라 
#        브로드캐스팅 된 인덱스의 형상을 반영

Out [1] :

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

 

Out [2] :

[ 2  5 11] 

 

Out [3] :

[[ 2  1  3]
 [ 6  5  7]
 [10  9 11]] 

 

Out [4] :

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

# NOTE : 결합 인덱싱
# 결합 인덱싱 : 배열값에 접근하고 수정하기에 매우 유연한 연산을 수행하게 해줌.
x = np.arange(12).reshape((3, 4))
row = np.array([0, 1, 2])
col = np.array([2, 1, 3])

print(x)
# NOTE : 팬시 인덱스와 단순 인덱스를 결합할 수 있다.
x[2, [2, 0, 1]]


# NOTE : 팬시 인덱싱과 마스킹을 결합할 수 있다.
mask = np.array([1, 0, 1, 0], dtype = bool)
x[row[:, np.newaxis], mask]

Out [1] :

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

 

Out [2] :

array([[ 0,  2],
       [ 4,  6],
       [ 8, 10]])

# NOTE : 팬시 인덱싱으로 값 변경하기
x = np.arange(10)
ind = np.array([2, 1, 8, 4])
x[ind] = 99
x[ind] -= 10
print(x)

Out [1] :

[ 0 89 89  3 89  5  6  7 89  9]

y = np.zeros(10)
y[[0, 0]] = [4 ,6]
print(y)

# output : [6. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
# NOTE : y[0] = 4가 할당되고 그 다음 y[0] = 6이 할당 되었다.

ind = [2, 3, 3, 4, 4, 4]
y[ind] += 1
print(y)

# output : [6. 0. 1. 1. 1. 0. 0. 0. 0. 0.]

# NOTE
# at : 지정한 값을 가진 특정 인덱스에 해당 연산자를 즉시 적용함.
z = np.zeros(10)
np.add.at(z, ind, 1)
print(z)

Out [1] :

[6. 0. 0. 0. 0. 0. 0. 0. 0. 0.]

 

Out [2] :

[6. 0. 1. 1. 1. 0. 0. 0. 0. 0.]

 

Out [3] :

[0. 0. 1. 2. 3. 0. 0. 0. 0. 0.]

# NOTE : NumPy 정렬
# np.sort는 기본적으로 퀵 정렬 알고리즘을 사용

x = np.array([2, 1, 4, 3, 5])
print(np.sort(x))

# NOTE : 정렬된 요소의 인덱스를 반환
ind = np.argsort(x)
ind

# NOTE : 행이나 열 기준으로 정렬
rand = np.random.RandomState(42)
y  = rand.randint(0, 10, (4, 6))
print(y)

# NOTE : 각 열을 정렬
print(np.sort(y, axis = 0), '\n')

# NOTE : 각 행을 정렬
print(np.sort(y, axis = 1))

# NOTE
# 부분정렬 : 파티션 나누기

# NOTE
# partition : 배열과 숫자 K를 취해 새로운 배열 반환
#             반환된 파티션의 왼쪽에는 K개의 가장 작은 값, 나머지 오른쪽에는 나머지 값을 임의의 순서로 채워짐.

x = np.array([7, 2, 3, 1, 6, 5, 4])
np.partition(x, 3)

Out [1] : 

[1 2 3 4 5]

 

Out [2] :

array([1, 0, 3, 2, 4], dtype=int64)

 

Out [3] :

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

 

Out [4] :

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


Out [5] :
[[3 4 6 6 7 9]
 [2 3 4 6 7 7]
 [1 2 4 5 7 7]
 [0 1 4 5 5 9]]

 

Out [6] :

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

 

참고

O'REILLY 제이크 밴더플래스 저/ 위키북스 김정인 역 - 파이썬 데이터 사이언스 핸드북

Comments