4. ndarray -데이터 형태 바꾸기(reshape,flatten)-
ndarray의 shape 형태를 바꿔보자.
import numpy as np
1. ravel(), np.ravel() - 다차원 배열 to 1차원 배열
ndarray의 형태를 바꾸는 함수 중 ravel함수와 np.ravel함수를 공부해보자.
ravel, np.ravel 중 편한 함수를 사용하면 된다. 결과가 같다.
ravel함수는 다차원의 배열을 1차원으로 변경해주는 함수로 order 파라미터를 갖는다
- 'C' 는 row를 우선 변경하고
- 'F' 는 column을 우선으로 변경한다.
# <in>
x = np.arange(15).reshape(3, 5)
x
# <out>
[[ 0 1 2 3 4] # 2차원 배열
[ 5 6 7 8 9]
[10 11 12 13 14]]
2차원 배열의 x를 ravel 함수를 이용하여 1차원 배열로 변경해보자.
# <in>
np.ravel(x)
# x.ravel()
# <out>
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]) # 1차원 벡터
위에서 언급한 것과 같이 ravel함수는 order parameter를 갖는다. order parmeter를 사용하여 ravel함수를 사용해보자.
# <in>
x = np.arange(15).reshape(3, 5)
np.ravel(x, order ='F')
# <out>
array([ 0, 5, 10, 1, 6, 11, 2, 7, 12, 3, 8, 13, 4, 9, 14]) # 열 우선 배열
# <in>
x = np.arange(15).reshape(3, 5)
np.ravel(x, order ='C')
# <out>
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]) # 행 우선 배열
order = 'C' 는 row 우선 배열, order = 'F'는 column을 우선 배열하는 것을 볼 수 있다.
2. flatten() 함수 - 다차원 배열 to 1차원 배열
ravel과 비슷한 함수로 flatten 함수가 있다.
ravel 함수와 flatten함수의 차이점은 flatten함수는 원본 데이터를 변경하는 것이 아닌 copy본을 생성하여 return한다는 것이다.
예시로 공부해보자.
# <in>
x = np.arange(15).reshape(3, 5)
y = np.ravel(x)
y[0] = 100
print(y)
print(x)
# <out>
[100 1 2 3 4 5 6 7 8 9 10 11 12 13 14]
[[100 1 2 3 4]
[ 5 6 7 8 9]
[ 10 11 12 13 14]]
ravel된 x를 y에 객체화하고 y의 0번째 인덱스를 100으로 바꿔준 뒤 x를 확인했을 때 x의 (0,0) 인덱스도 바뀐 것을 볼 수 있다.
이제 flatten 함수로 같은 과정의 결과를 확인해보자.
# <in>
x = np.arange(15).reshape(3, 5)
y = x.flatten()
y[0] = 100
print(x)
print(y)
# <out>
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]]
[100 1 2 3 4 5 6 7 8 9 10 11 12 13 14]
ravel과 다르게 flatten함수는 원본은 바뀌지 않고 객체화한 y에만 변경이 닿은 것을 확인할 수 있다.
3. reshape() 함수
reshape함수는 앞서 몇 번 경험을 해봤다. reshape함수는 ndarray 의 차원을 변경해주는 함수이다.
reshape함수 사용시 주의할 점은
1. reshape한 후의 결과의 전체 원소 개수가 이전의 원소 개수와 같아야 한다는 것이다.
사용의 예를 들어보자면, 이미지 데이터를 벡터화할 때인데, 이미지는 기본적으로 2차원 혹은 3차원(RGB)이나 트레이닝을 위해 1차원을 변경하여 사용해야 하는 경우가 있다. 이 경우 reshape함수를 사용해서 다차원의 공간을 1차원으로 바꿔 줄 수 있다.
# <in>
x = np.arange(36)
print(x)
print(x.shape)
print(x.ndim)
# <out>
[ 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]
(36,)
1
# <in>
x = np.arange(36)
y = x.reshape(6, 6)
print(x.shape)
print(y.shape)
print(y.ndim)
# <out>
(36,)
(6, 6)
2
3차원을 reshape 함수를 사용하여 만드려면 3개의 인자를 넣어줘야 한다.
# <in>
x = np.arange(36)
k = x.reshape(3, 4, 3)
print(k.ndim)
# <out>
3
하지만 이런 작은 숫자가 아닌 큰 숫자에서 마지막 숫자를 정하기 곤란한 경우 -1을 입력하면 자동으로 함수가 숫자를 찾아서 적용해준다.
# <in>
x = np.arange(36)
k = x.reshape(3, 4, -1)
print(k.ndim)
# <out>
3