학습내용
#1 : 넘파이 브로드캐스팅(Broadcasting rules) #2 : 넘파이 인덱싱(Advanced Indexing and index tricks)동 #3 : Bool로 인덱싱하기(Indexing with Boolean Arrays) #4 : ix_() function |
#1 : 넘파이 브로드캐스팅(Broadcasting rules)
브로드캐스팅은 단순하게 편리성을 위해 shape(차원 혹은 다른 행과 열)이 다른 np.array끼리 연산을 지원해준다. 차원(ndim)이 같고 각 축(axis)의 값이 같거나 1일 때만 기본적으로 연산이 가능하지만 브로드캐스팅을 통해 행과 열의 개수가 다르더라고 계산할 수 있다. 연산시 부족한 행과 열의 추가(자기 자신을 복제)되어 연산이 가능하도록 만들어준다.
import numpy as np
np.ones((3,4))
# array([[1., 1., 1., 1.],
# [1., 1., 1., 1.],
# [1., 1., 1., 1.]])
np.arange(4)
# array([0, 1, 2, 3])
np.ones((3,4)) * np.arange(4)
# array([[0., 1., 2., 3.],
# [0., 1., 2., 3.],
# [0., 1., 2., 3.]])
np.arange(3).reshape(3,1) * np.arange(3)
#2 : 인덱스 배열로 인덱싱하기(Indexing with Arrays of Indices)
인덱스를 가진 배열로 인덱싱을 할 수 있다. 배열로 인덱싱을 하면 배열의 각 값에 따라 인덱싱 값을 구할 수 있다. 배열로 인덱싱을 할 경우 인덱싱을 하고있는 배열의 차원이 유지된다.
a = np.arange(12)**2
a
# array([ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121])
#인덱스 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
i = np.array([1,1,3,8,5])
a[i]
# array([ 1, 1, 9, 64, 25])
j = np.array([[3,4],[9,7]])
a[j]
# array([[ 9, 16],
# [81, 49]])
2) 인덱싱 코드 예시
palette = np.array([[0, 0, 0], # black
[255, 0, 0], # red
[0, 255, 0], # green
[0, 0, 255], # blue
[255, 255, 255]]) # white
image = np.array([[0, 1, 2, 0],
[0, 3, 4, 0]])
palette[image]
# array([[[ 0, 0, 0],
# [255, 0, 0],
# [ 0, 255, 0],
# [ 0, 0, 0]],
# [[ 0, 0, 0],
# [ 0, 0, 255],
# [255, 255, 255],
# [ 0, 0, 0]]])
- 위 코드에서 image에서 ([[0, 1, 2, 0], [0, 3, 4, 0]])은 2차원이기에 열 값을 가져오는 것이 아니라 행 값을 가져온다. 따라서, [0, 1, 2, 0]은 2차원 배열 안에서 1행, 2행, 3행, 1행을 가져오고, [0, 3, 4, 0]은 2차원 배열 안에서 1행, 4행, 5행, 1행을 가져온다.
- 행을 가져왔기 때문에 2차원에서 3차원으로 바뀌게 된다.
time = np.linspace(20, 145, 5)
time
# array([ 20. , 51.25, 82.5 , 113.75, 145. ])
data = np.sin(np.arange(20)).reshape(5,4)
data
# array([[ 0. , 0.84147098, 0.90929743, 0.14112001],
# [-0.7568025 , -0.95892427, -0.2794155 , 0.6569866 ],
# [ 0.98935825, 0.41211849, -0.54402111, -0.99999021],
# [-0.53657292, 0.42016704, 0.99060736, 0.65028784],
# [-0.28790332, -0.96139749, -0.75098725, 0.14987721]])
ind = data.argmax(axis=0) #행 기준 가장 높은 값을 가지고 있는 인덱스
ind
# array([2, 0, 3, 1])
time_max = time[ind]
time_max
# array([ 82.5 , 20. , 113.75, 51.25])
data_max = data[ind, range(data.shape[1])] #ind는 행, range는 열에 접근하는 것
data_max
# array([0.98935825, 0.84147098, 0.99060736, 0.6569866 ])
np.all(data_max == data.max(axis=0)) #all함수는 모든 값이 참이면 True 반환
# True
- data_max는 data의 2,0 / 0,1 / 3,2 / 1,3의 값을 가져온다.
- shape[1]은 전체 열 개수를 반환하며, shpae[0]은 전체 행을 반환한다.
- 위 코드에서 range(data.shape[1])는 range(4)를 의미한다.
#3 : Bool로 인덱싱하기(Indexing with Boolean Arrays)
Bool 타입을 가진 값들로도 인덱싱이 가능하다. 원하는 값만 남기거나 변환할 때 유용하다. 구조를 잘 기억할 것.
a = np.arange(12).reshape(3, 4)
a
# array([[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11]])
b = a > 4
b
# array([[False, False, False, False],
# [False, True, True, True],
# [ True, True, True, True]])
#불타입으로 인덱싱 True 값에 대응하는 것만 반환
a[b]
# array([ 5, 6, 7, 8, 9, 10, 11])
#True 값을 모두 0으로 바꿔준다
a[b] = 0
a
# array([[0, 1, 2, 3],
# [4, 0, 0, 0],
# [0, 0, 0, 0]])
#4 : ix_() function
.ix_() 을 통해 서로 다른 shape(차원 혹은 다른 행과 열)을 가진 배열들을 묶어서 처리할 수 있다.
a = np.array([2,3,4,5])
b = np.array([8,5,4])
c = np.array([5,4,6,8,3])
ax, bx, cx = np.ix_(a,b,c)
ax
# array([[[2]],
# [[3]],
# [[4]],
# [[5]]])
bx
# array([[[8],
# [5],
# [4]]])
cx
# array([[[5, 4, 6, 8, 3]]])
ax.shape, bx.shape, cx.shape
# ((4, 1, 1), (1, 3, 1), (1, 1, 5))
result = ax + bx * cx
result
# array([[[42, 34, 50, 66, 26],
# [27, 22, 32, 42, 17],
# [22, 18, 26, 34, 14]],
# [[43, 35, 51, 67, 27],
# [28, 23, 33, 43, 18],
# [23, 19, 27, 35, 15]],
# [[44, 36, 52, 68, 28],
# [29, 24, 34, 44, 19],
# [24, 20, 28, 36, 16]],
# [[45, 37, 53, 69, 29],
# [30, 25, 35, 45, 20],
# [25, 21, 29, 37, 17]]])
result[3, 2, 4] #3차원에서 4행, 2차원 3행, 5열
# 17
a[3] + b[2] *c[4]
# 17
'파이썬 > Numpy(넘파이)' 카테고리의 다른 글
[NumPy] 4. 넘파이 차원 변환(Shape Manipulation) (0) | 2021.10.13 |
---|---|
[NumPy] 3. 넘파이 인덱싱, 슬라이싱, 반복(indexing, slicing, iterating) (0) | 2021.10.12 |
[NumPy] 2. 넘파이 연산, 축, 배열 출력 (0) | 2021.10.12 |
[NumPy] 1. 넘파이 개념, ndarray, 배열 생성 (0) | 2021.10.12 |
댓글