from palette import colorful_colors

[Numpy] (마무리) N차원 배열 차원 변경: reshape(), resize() 본문

CS 학부과목/Python

[Numpy] (마무리) N차원 배열 차원 변경: reshape(), resize()

colorful-palette 2023. 1. 29. 23:47

<목차>
1. 1차원 2차원
2. 1차원 n차원
3. n차원 1차원
3. n차원 n차원
4. reshape()과 resize()차이



넘파이에선 차원을 바꿀 수 있는 함수인(형변환) reshape()과 resize()를 제공한다.
먼저 reshape()을 살펴보자.

1. 1차원 2차원

1차원 배열 만들기:

arr1 = np.arange(10)
print(arr1)
print(f'[arr1] shape:{arr1.shape} ndim:{arr1.ndim}차원')


# 출력결과:
# [0 1 2 3 4 5 6 7 8 9]
# [arr1] shape:(10,) ndim:1차원

예시를 들기 위해 1차원 배열을 만들자. shape과 ndim에서 1차원임을 알 수 있다.



1차원 → 2차원 변경:

arr1_1 = arr1.reshape(2, 5)  		# 2행 5열로 변경
print(arr1_1)
print(f'\n[arr1_1] shape:{arr1_1.shape} ndim:{arr1_1.ndim}차원')


# 출력결과:
[[0 1 2 3 4]
 [5 6 7 8 9]]

[arr1_1] shape:(2, 5) ndim:2차원

1차원 10행 1열 배열을 2차원 2행 5열 배열로 바꿨다.
reshape을 할 때 주의점은, reshape를 하더라도전체 원소의 총 개수는 고정이라는 점이다.
이때 지정한 크기와 (2x5) 원본 배열에 있는 원소의 개수(10)가 다르면 에러가 발생한다. (아귀가 맞아야 한다)
ex) 2x5 = 10 이므로 에러가 발생하지 않았다.

-1 이용하기

-1을 이용해 1차원 → 2차원 바꾸기:

arr1_2 = arr1.reshape((5, -1))    # 크기에 -1로 설정하면 해당 행 or 열을 알아서 조정해준다.
print(arr1_2)
print(f'\n[arr1_2] shape:{arr1_1.shape} ndim:{arr1_1.ndim}차원')


# 출력결과:
[[0 1]
[2 3]
[4 5]
[6 7]
[8 9]]

[arr1_2] shape:(2, 5) ndim:2차원

넘파이는 배열의 크기를 자동으로 지정하는 기능도 제공한다. 크기에 -1을 지정하면 나머지 원소 개수로 모두 채우라는 의미다. 위 예시에선 5행 2열을 만들때 첫 번째 크기를 5, 두 번째 크기를 나머지 원소 개수로 채우도록 했다.

2. 1차원 n차원

reshape의 기본 형식 '바꿀배열 = (기존배열, (shape))'을 이용해 1차원을 n차원으로 바꿔보자. 아래의 코드는 arr2을 2x2x3인 3차원으로 변경하라는 예시다. 괄호 안이 총 요소 개수만 일치한다면 어떤 차원이라도 변경 가능하다.

arr2 = np.arange(12)
arr2 = np.reshape(arr2, (2,2,-1))   # 2x2x3 배열로 변경
print(arr2)
print(f'\n[arr2] shape:{arr2.shape} ndim:{arr2.ndim}차원')


# 출력결과:
[[[ 0 1 2]
  [ 3 4 5]]

 [[ 6 7 8]
  [ 9 10 11]]]

[arr2] shape:(2, 2, 3) ndim:3차원


3차원으로 변경된 것을 알 수 있다.

3. n차원 1차원

arr2.reshape(12)    #3차원 -> 1차원으로 만들기


# 출력결과:
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])

n차원에서 1차원으로 다시 변경하는건 간단하다. reshape() 안에 전체 원소 개수를 넣으면 된다.
더 쉬운 방법으로는 reshape(-1)로도 같은 결과를 얻을 수 있다.

4. n차원 n차원

위의 예시들처럼, 배열의 전체 원소 개수만 맞춘다면 바꿀배열 = reshape(기존배열, (n,n, ..., n)) 으로 차원을 바꿀 수 있다.

5. reshape()과 resize()차이

reshape은 전체 원소의 총 개수는 고정이지만, resize는 변경된다는 점이 차이점이다. 
reshape은 전체 원소의 개수가 다르면 오류가 나지만, resize는 자동으로 맞춰준다.
또한 resize는 반환값이 없이, 배열이 바로 바뀐다는 점이 있다.
예시로 살펴보자.
a=np.array([[0,1],[2,3]])
print(np.resize(a,(2,4)))      # resize는 return값이 없기 때문에 보통 이렇게 작성한다.


# 출력결과:
[[0 1 2 3]
 [0 1 2 3]]


2차원 배열인 a를 같은 2차원 2행 4열로 늘리는 예제다.
reshape이었다면 총 원소개수가 맞지 않아 오류가 났겠지만, resize는 자동으로 사이즈를 맞춰준다.




resize 응용 예시:
예를 들어 (28, 28) 인 2차원 흑백 이미지를 모델에 집어넣기 위해 (28, 28, 1) 3차원로 바꿀때:
reshape으로는 차원이 바뀌지 않는다. resize(28, 28, 1)을 이용하면 3차원으로 바뀐다.




reference: https://numpy.org/doc/stable/reference/generated/numpy.resize.html