[NumPy] 넘파이 reshape() 함수
- -
넘파이 reshape() 함수
넘파이(Numpy)의 reshape() 함수는 다차원 배열의 모양(형태)을 변경할 때 사용되는 함수이다. reshape() 함수를 사용하여 배열의 차원을 바꾸거나 배열의 구조를 재정의할 수 있다.
reshape() 함수의 기본 구문
numpy.reshape(a, newshape, order='C')
- a - 모양을 변경하려는 배열(리스트, 튜플 모두 가능)
- newshape - 변경하려는 새로운 모양이다. 이것은 튜플 또는 정수값의 나열로 제공된다. 새로운 모양은 원래 배열의 원소 수와 일치해야 한다.(예 : 3차원 배열로 변경하려면 3을 넣으면 된다.)
- order(선택적) - 요소의 저장 순서를 지정한다. 'C'(기본값)는 행 주위의 데이터 저장 순서를 나타내며, 'F'는 열 주위의 데이터 저장 순서를 나타낸다.
방법 1
np.reshape(원본배열, newshape)
방법 2
원본배열.reshape(newshape)
위의 두 방법 모두 가능하니 편한 방법을 선택해서 사용하면 될 것 같다.
예를 들어, 1차원 배열을 2차원 배열로 변경하거나 2차원 배열을 1차원 배열로 변경하려면 다음과 같이 reshape() 함수를 사용할 수 있다.
import numpy as np
# 1차원 배열을 2차원 배열로 변경
arr1d = np.array([1, 2, 3, 4, 5, 6])
arr2d = arr1d.reshape((2, 3))
print(f'1차원 → 2차원 : {arr2d}')
# 2차원 배열을 1차원 배열로 변경
arr1d_new = arr2d.reshape(6)
print(f'2차원 → 1차원 : {arr1d_new}')
1차원 → 2차원 : [[1 2 3]
[4 5 6]]
2차원 → 1차원 : [1 2 3 4 5 6]
실행 결과
reshape() 함수를 사용하면 배열의 형태를 변경하고 데이터를 유지할 수 있으므로 데이터의 재구성을 쉽게 수행할 수 있다. 다차원 배열을 다른 형태로 재구성할 때 모양의 원소 수를 일치시키는 것이 중요하며, 그렇지 않으면 오류가 발생할 수 있다.
Tip
arr1d = np.array([1, 2, 3, 4, 5, 6])
arr2d = arr1d.reshape([2, 3])
print(arr2d)
arr1d = np.array((1, 2, 3, 4, 5, 6))
arr2d = arr1d.reshape((2, 3))
print(arr2d)
arr1d = np.array([1, 2, 3, 4, 5, 6])
arr2d = arr1d.reshape(2, 3)
print(arr2d)
reshape의 새로운 배열 모양을 지정할 때 위의 세 방법 모두 가능하니 참고하자. 세 개의 예제 코드를 전부 실행하면 아래와 같이 모두 같은 결과를 확인할 수 있다.
[[1 2 3]
[4 5 6]]
실행 결과
reshape() 함수를 사용할 때 모양(새로운 형태)의 원소 수가 원래 배열의 원소 수와 일치하지 않는 경우의 예제를 아래에서 한 번 살펴보자.
import numpy as np
# 원소 수가 일치하지 않는 형태로 reshape 시도
arr1d = np.array([1, 2, 3, 4, 5, 6])
arr_error = arr1d.reshape((2, 4)) # 오류: 원소 수가 일치하지 않음
# ValueError: cannot reshape array of size 6 into shape (2,4)
위의 예제에서 원래 1차원 배열은 6개의 원소를 가지고 있지만, reshape((2,4))의 형태로 변경하려고 하면 원소 수가 일치하지 않아 오류가 발생한다. reshape() 함수를 사용할 때 모양을 변경할 수 있는 범위는 원래 배열의 원소 수와 동일한 범위 내에서 정의되어야 한다. 이로 인해 원소 수가 일치하지 않으면 ValueError 오류가 발생한다.
다음은 2차원 배열에서 3차원 배열로 reshape 하는 예제를 살펴보자.
import numpy as np
# 2차원 배열 생성
arr2d = np.array([[1, 2, 3], [4, 5, 6]])
# 2차원 배열을 3차원 배열로 변경 (2x3x1 형태)
arr3d = arr2d.reshape(2, 3, 1)
print("Original 2D Array")
print(arr2d)
print("Reshaped 3D Array")
print(arr3d)
Original 2D Array
[[1 2 3]
[4 5 6]]
Reshaped 3D Array
[[[1]
[2]
[3]]
[[4]
[5]
[6]]]
실행 결과
(2,3,1) 형태는 3차원 배열의 모양(shape)을 나타낸다. 각 숫자는 해당 차원의 크기를 나타내며, 차원은 배열의 중첩 수준을 나타낸다. 여기에서 (2,3,1) 형태의 3차원 배열은 다음과 같이 해석될 수 있다.
- 첫 번째 차원(2) - 배열은 2개의 요소를 가지고 있다. 이것은 배열의 "깊이"를 나타낸다.
- 두 번째 차원(3) - 각 깊이 내에서 배열은 3개의 요소를 가지고 있다. 이것은 배열의 "행"을 나타낸다.
- 세 번째 차원(1) - 각 행 내에서 배열은 1개의 요소를 가지고 있다. 이것은 배열의 "열"을 나타낸다.
조금 더 이해하기 쉽게 각 차원마다 색을 칠하여 아래와 같은 형태로 보면 이해하는데 조금 더 도움이 되지 않을까 싶다.
[
[
[1]
[2]
[3]
]
[
[4]
[5]
[6]
]
]
첫 번째 차원 안에 2개의 요소가 들어간다.(빨간색 안에 2개의 요소)
두 번째 차원 안에 3개의 요소가 들어간다.(파란색 안에 각각 3개의 요소)
세 번째 차원 안에 1개의 요소가 들어간다.(초록색 안에 각각 1개의 요소)
즉, (2,3,1) 형태의 3차원 배열은 2개의 깊이(깊이 1과 깊이 2), 각 깊이에서 3개의 행, 그리고 각 행에서 1개의 열을 가지고 있는 배열을 나타낸다. 이러한 형태는 데이터를 특정한 방식으로 구조화하거나 표현하는 데 사용할 수 있다.
위에서 2차원에서 3차원으로 변경하는 예제를 잘 이해했다면 아래 2차원 → 4차원 예제도 같은 원리로 동작하니 이해하기 수월할 것이다.
import numpy as np
# 1차원 배열 생성
arr1d = np.array([1, 2, 3, 4, 5, 6, 7, 8])
# 1차원 배열을 4차원 배열로 변경 (2x2x2x1 형태)
arr4d = arr1d.reshape(2, 2, 2, 1)
print("Original 1D Array")
print(arr1d)
print("Reshaped 4D Array")
print(arr4d)
Original 1D Array
[1 2 3 4 5 6 7 8]
Reshaped 4D Array
[[[[1]
[2]]
[[3]
[4]]]
[[[5]
[6]]
[[7]
[8]]]]
실행 결과
위의 예제 코드는 처음에는 1차원 배열 arr1d가 생성되고 reshape() 함수를 사용하여 4차원 배열 arr4d로 변경된다. 결과적으로 arr4d는 (2,2,2,1) 형태의 4차원 배열이 된다.
reshape() 함수의 매개변수로 -1을 사용하는 경우, 해당 차원의 크기를 자동으로 계산하라는 의미이다. 이것은 주로 특정 차원의 크기를 사용자가 직접 지정하지 않고, 나머지 차원의 크기를 통해 자동으로 계산하고자 할 때 사용된다. 예를 들어, 1차원 배열이 [1,2,3,4,5,6]이라고 가정해 보자. 이를 2 x 3의 2차원 배열로 변환하려면 다음과 같이 할 수 있다.
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6])
reshaped_arr = arr.reshape(2, 3)
print(reshaped_arr)
그러나 만약 우리가 두 번째 차원의 크기를 직접 지정하지 않고 나머지에 맡기고 싶다면,이때 아래와 같이-1을 사용한다.
reshaped_arr_auto = arr.reshape(2, -1)
print(reshaped_arr_auto)
[[1 2 3]
[4 5 6]]
실행 결과
reshape(2, -1)의 경우, NumPy에게 두 번째 차원의 크기를 자동으로 계산하여 2차원 배열을 만들라고 지시한다. 첫 번째 차원은 2로 고정되어 있고, 두 번째 차원의 크기는 자동으로 계산된다. 이때 자동으로 계산되는 크기는 원래 배열의 요소 수를 기반으로 결정된다. 간단히 말해서, reshape(2, -1)는 2차원 배열을 만들되, 두 번째 차원의 크기는 자동으로 결정하라는 의미이다. 결과적으로 원본 배열의 요소 개수가 6개이고 새롭게 생성할 배열의 첫 번째 차원을 2로 설정하였기 때문에 6 / 2 = 3이므로 -1의 계산 결과는 3이 된다. 따라서 위의 코드는 reshape(2,3)을 실행한다.
여기서 주의할 점은 -1을 설정하였을 때 자동으로 크기를 계산해 주어도 원본 배열의 원소 개수와 새로 만들 배열의 원소 개수가 일치하지 않는다면 오류가 발생한다. 예를 들어 [1,2,3,4,5]의 1차원 배열이 있을 때 해당 배열을 reshape(2, -1)을 실행시키면 오류가 발생한다.
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
reshaped_arr = arr.reshape(2, -1)
print("\n원래 배열")
print(arr)
print("\n2차원 배열")
print(reshaped_arr)
ValueError: cannot reshape array of size 5 into shape (2,newaxis)
위의 예제에서는 1차원 원본 배열의 요소가 총 5개이다, 그리고 reshape() 함수로 첫 번째 차원을 2로 설정하였다 그러면 새롭게 생성될 2차원 배열의 행이 2이라는 의미로 인식하는데 5는 2로 나누어 떨어지지 않기 때문에 나머지 요소 1개가 남게 되어 reshape을 할 수가 없다. 따라서 reshape 함수를 사용할 때 원본 배열의 요소 수가 새롭게 생성할 배열의 첫 번째 차원 크기로 나누어 떨어져야 호환이 될 수 있다, 그렇지 않으면 위의 예제처럼 ValueError를 발생시킨다.
읽어주셔서 감사합니다.
'Library > NumPy' 카테고리의 다른 글
[NumPy] 넘파이 flatten() 함수 (0) | 2023.11.21 |
---|---|
[NumPy] 넘파이 resize() 함수 (0) | 2023.11.19 |
[NumPy] 넘파이 다차원 배열 연산 (0) | 2023.11.15 |
[NumPy] 넘파이 다차원 배열 검색 (0) | 2023.11.04 |
[NumPy] 넘파이 스칼라와 벡터 (0) | 2023.09.12 |
소중한 공감 감사합니다