Numpy 응용
axis 이해하기
axis : 축.
- 축이란, 데이터가 추가되는 방향
예를 들어 3차원 배열(3, 4, 5) 배열이 있다면 - 1차원 배열에 추가되는 것은 0차원 스칼라
- 2차원 배열에 추가되는 것은 1차원 배열
- 3차원 배열에 추가되는 것은 2차원 배열
ex_1 = np.arange(1, 61).reshape(3, 4, 5)
# 3차원 배열에 추가되는 2차원 배열 3개
# 2차원 배열에 추가되는 1차원 배열 4개
# 1차원 배열에 추가되는 0차원 스칼라 5개
ex_1 ~~> array([[[ 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10],
[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20]],
[[21, 22, 23, 24, 25],
[26, 27, 28, 29, 30],
[31, 32, 33, 34, 35],
[36, 37, 38, 39, 40]],
[[41, 42, 43, 44, 45],
[46, 47, 48, 49, 50],
[51, 52, 53, 54, 55],
[56, 57, 58, 59, 60]]])
arr = np.arange(1, 37).reshape(3, 4, 3)
# 3차원 배열에 추가되는 2차원 배열 3개,
# 2차원 배열에 추가되는 1차원 배열 4개,
# 1차원 배열에 추가되는 0차원 스칼라 3개
arr ~~> array([[[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[10, 11, 12]],
[[13, 14, 15],
[16, 17, 18],
[19, 20, 21],
[22, 23, 24]],
[[25, 26, 27],
[28, 29, 30],
[31, 32, 33],
[34, 35, 36]]])
axis : 축의 인덱스
위의 예에서는 3차원 배열기기 때문에 축이 3가지
- 2차원 배열이 추가되는 axis=0
- 1차원 배열이 추가되는 axis=1
- 0차원 스칼라가 추가되는 axis:2
각 축별 최댓값(max) 뽑아내기
np.max(arr, axis = 0)
~~> array([[25, 26, 27],
[28, 29, 30],
[31, 32, 33],
[34, 35, 36]])
np.max(arr, axis = 1)
~~> array([[10, 11, 12],
[22, 23, 24],
[34, 35, 36]])
np.max(arr, axis = 2)
~~> array([[ 3, 6, 9, 12],
[15, 18, 21, 24],
[27, 30, 33, 36]])
인덱스와 슬라이싱
인덱싱(Indexing) : 무엇인가를 가르킨다
라는 의미
슬라이싱(Slicing) : 무엇인가를 잘라낸다
라는 의미
- 인덱스로 요소에 접할할때는 하나씩만 접근이 되지만 슬라이싱은 인덱스를 사용하여 범위를 정한 후 시퀀스 객체의 요소에 접근
- 시퀀스객체[ 시작 인덱스 : 끝 인덱스 ]
arr = np.arange(1, 11).reshape(2, 5)
arr
~~> array([[ 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10]])
arr[0] # arr 배열의 0번째 행 선택
~~> array([1, 2, 3, 4, 5])
arr[0][2] # arr 배열의 0번째 행, 2번째 열
~~> 3
arr[0, 2]
~~> 3
특정 차원의 배열을 전체 선택하기 위해 쓰는 연산자 => :
arr[:, 2] # 2차원 배열 전체 중 각 열의 2번째 것
~~> array([3, 8])
arr = np.arange(1, 37).reshape(3, 4, 3)
arr
~~> array([[[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[10, 11, 12]],
[[13, 14, 15],
[16, 17, 18],
[19, 20, 21],
[22, 23, 24]],
[[25, 26, 27],
[28, 29, 30],
[31, 32, 33],
[34, 35, 36]]])
arr[1, 1:3] # 3차원 배열 중 1번째, 1행부터 3행 전까지
~~> array([[16, 17, 18],
[19, 20, 21]])
arr = np.arange(36).reshape(2, 3, 3, 2)
arr
~~> array([[[[ 0, 1],
[ 2, 3],
[ 4, 5]],
[[ 6, 7],
[ 8, 9],
[10, 11]],
[[12, 13],
[14, 15],
[16, 17]]],
[[[18, 19],
[20, 21],
[22, 23]],
[[24, 25],
[26, 27],
[28, 29]],
[[30, 31],
[32, 33],
[34, 35]]]])
arr[0, :, :, 0]
~~> array([[ 0, 2, 4],
[ 6, 8, 10],
[12, 14, 16]])
✔ 3차원, 0차원 제외하고 1, 2 차원 데이터 전체를 가지고 오고 싶다.
- 스프레드 연산자(
...
)
arr[0, ..., 0] # 3차원과 0차원 사이에 있는 모든 데이터를 선택
~~> array([[ 0, 2, 4],
[ 6, 8, 10],
[12, 14, 16]])
배열의 차원과 형상
- 형상(shape)
- 차원수(ndim)
arr = np.arange(12).reshape(3, 4)
arr
~~> array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
arr.shape
~~> (3, 4)
arr.ndim
~~> 2
차원수 확장하기
- 보통 기초적인 딥러닝에서 이미지 분석을 위한
CNN
을 활용할 때 데이터를 전처리하기 위해 사용한다. - tensorflow는
tf.newaxis
, numpy는np.newaxis
를 활용해서 추가 차원을 만들어 낼 수 있다. - tesnsorflow에서
CNN
을 위한 이미지 데이터 형태는 항상 (N, H, W, C
)를 유지한다.N
:BATCH_SIZE
H
: 이미지 세로 픽셀( 세로 크기 )W
: 이미지 가로 픽셀( 가로 크기 )C
: 이미지의 채널 수( 컬러이미지 RGB:3, 흑백이미지 Grayscale: 1 )
만약 이미지를 크롤링해서 가져오면 가로, 세로 크기 밖에 없다. ( H, W
)로 이루어진 2차원 배열이다. 이걸 4차원 배열 형태로 바꿔줘야만 한다.
arr = np.arange(784).reshape(28, 28)
arr.shape
~~> (28, 28)
(28, 28
)은 2차원 배열 -> (H, W
)만 존재하는 경우이다. 이를 4차원 형태로 강제로 만들어줘야 CNN
레이어에 입력이 가능하다. (1, 28, 28, 1
)
temp_arr = arrpnp.newaxis, :, :, np.newaxis]
temp_arr.shape
~~> (1, 28, 28, 1)
또는
temp_app2 = arr[np.newaxis, ..., np.newaxis]
temp_arr2.shape
~~> (1, 28, 28, 1)
차원 쥐어 짜기
np.squeeze
- 개수가 1인 차원의 내용을 없애는 기법
temp_squeeze = np.squeeze(temp_arr)
temp_squeeze.shape
~~> (28, 28)
배열의 형상(shape) 바꾸기
np.newaxis
를 활용하면 축을 하나 추가하게 된다. ( ▶ 차원 수를 늘린다 )np.squeeze
를 활용하면 개수가 1인 차원의 데이터를 삭제 ( ▶ 차원 수를 줄인다 )
평탄화revel
: 원본 배열을 평탄화 시킨 참조 배열 을 만들어 낸다. (이를 View 또는 Reference 라고 한다 )flatten
: 원본 배열을 평탄화 시킨 복사된 배열 을 만들어 낸다.
ravel
x = np.arange(15).reshape(3, 5)
x.shape
~~> (3, 5)
x
~~> array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
temp = np.ravel(x)
temp.shape
~~> (15, )
temp
~~> array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
x
~~> array([[100, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[ 10, 11, 12, 13, 14]])
temp를 변경했는데도 x도 변경 되어있다. ravel은 c의 포인터 개념
flatten
- flattn은 ravel과 다르게 실제 1차원 배열을 새롭게 만들어 낸다.
x = np.arange(15).reshape(3, 5)
x
~~> array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
temp_flatten = x.flatten()
temp_flatten
~~> array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
temp_flatten[0] = 100
temp_flatten
~~> array([ 100, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
x
~~> array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
temp_flatten이 변경되어도 x는 변경되지 않는다.
데이터를 조금 더 안전하게 관리해야 하기 때문에 ravel보다는 flatten을 더 많이 쓴다.
reshape
x = np.arange(20)
x
~~> array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19])
- reshape 함수내의 모든 숫자를 곱했을 때 스칼라 원소의 개수와 같기만 하면 형상 변환이 가능하다.
x.reshape(2, 5, 2)
~~> array([[[ 0, 1],
[ 2, 3],
[ 4, 5],
[ 6, 7],
[ 8, 9]],
[[10, 11],
[12, 13],
[14, 15],
[16, 17],
[18, 19]]])
x.size # 스칼라 원소의 개수 구하기
~~> 20
-1을 reshape에 넣으면 남는 숫자를 자동을 계산해 준다.
-1
은 하나만 지정을 해줄 수 있다.
x.reshape(2, -1, 2) # -1이 자동으로 5로 지정된다.
~~> array([[[ 0, 1],
[ 2, 3],
[ 4, 5],
[ 6, 7],
[ 8, 9]],
[[10, 11],
[12, 13],
[14, 15],
[16, 17],
[18, 19]]])
x.reshape(2, 2, -1).shape
(2, 2, 5)
브로드 캐스팅
- 차원 수가 다른 배열끼리의 연산
- 차원이 달라도 0차원 스칼라의 개수가 똑같으면 연산이 가능
- 저차원의 배열을 고차원으로 확장
- 수학적으로는 고차원 배열의 shape과 똑같은 일벡터를 만들어서 저차원과 곱한 배열을 만들어 계산
x = np.arange(20).reshape(4, 5)
y = np.arange(20, 40).reshape(4, 5)
x.shape, y.shape
~~> (4, 5), (4, 5))
x + y
~~> array([[20, 22, 24, 26, 28],
[30, 32, 34, 36, 38],
[40, 42, 44, 46, 48],
[50, 52, 54, 56, 58]])
x * 2 # 일벡터에 전부 2를 곱해줘 2로 채운 후 x와 곱
~~> array([[ 0, 2, 4, 6, 8],
[10, 12, 14, 16, 18],
[20, 22, 24, 26, 28],
[30, 32, 34, 36, 38]])
shape이 다를 때의 연산
a = np.arange(12).reshape(4, 3)
b = np.arange(100, 103)
c = np.arange(1000, 1004)
d = b.reshape(1, 3)
a.shape, b.shape, c.shape, d.shape
~~> ((4, 3), (3, ), (4, ), (1, 3))
a
~~> array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
b
~~> array([100, 101, 102])
a의 행, 열과 b의 행, 열 중 a의 열, b의 행이 같기 때문에 더할 수 있다.
a + b
~~> array([[100, 102, 104],
[103, 105, 107],
[106, 108, 110],
[109, 111, 113]])
c
~~> array([1000, 1001, 1002, 1003])
a + c는 a와 c가 같은 수의 행이나 열이 없기 때문에 더해질 수 없다.
a의 행, 열과 d의 행, 열 중 a의 열, d의 열이 같기 때문에 더할 수 있다.
d
~~> array([[100, 101, 102]])
a + d
~~> array([[100, 102, 104],
[103, 105, 107],
[106, 108, 110],
[109, 111, 113]])
전치행렬 만들기
- 행렬 A의 행과 열의 인덱스를 바꾼 것을 전치행렬 이라고 한다.
- 의 위치를 로 바꾼 것
- 보통 Transpose 했다고 이야기 한다.
A = np.arange(6).reshape(2, 3)
A
~~> array([[0, 1, 2],
[3, 4, 5]])
- ndarray에서 T만 호출해 주면 전치행렬이 완성된다.
A.T
~~> array([[0, 3],
[1, 4],
[2, 5]])
역전파를 사용할 때 사용이 된다.
Author And Source
이 문제에 관하여(Numpy 응용), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@ksj5738/Numpy-응용저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)