[Python NumPy] reshape에서 -1 은 무슨 의미인가? (reshape(-1, 1))
Python 분석과 프로그래밍/Python 데이터 전처리 2018. 1. 25. 23:56파이썬 NumPy 에서 배열의 차원(Dimension)을 재구조화, 변경하고자 할 때 reshape() 메소드를 사용합니다. 가령, 3개의 행과 4개의 열로 구성된 2차원의 배열로 재설정하고 싶으면 reshape(3, 4) 처럼 reshape()의 매개변수로 변경하고자 하는 배열의 행과 열의 차원을 정수로 입력해주면 됩니다.
그런데 reshape(-1, 2) 혹은 reshape(3, -1) 처럼 reshape() 메소드 안에 '-1'이 들어가 있는 경우가 있습니다. 이때 reshape()의 '-1'이 의미하는 바는, 변경된 배열의 '-1' 위치의 차원은 "원래 배열의 길이와 남은 차원으로 부터 추정"이 된다는 뜻입니다. (One shape dimension can be -1. In this case, the value is inferred from the length of the array and remaining dimensions.)
말이 좀 어렵고, 금방 이해하기가 쉽지 않은데요, ^^; 아래에 간단한 예를 들어서 설명해보겠습니다.
먼저 NumPy 라이브러리를 import 하고 3x4 차원의 예제 배열을 만들어보겠습니다.
(우리가 일상적으로 사용하는 reshape() 의 사용 예제)
In [1]: import numpy as np In [2]: x = np.arange(12).reshape(3, 4) In [3]: x.shape Out[3]: (3, 4) In [4]: x Out[4]: array([[ 0, 1, 2, 3], [ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
|
(1) reshape(-1, 정수) 의 행(row) 위치에 '-1'이 들어있을 경우 |
이제 reshape() 의 행(row) 차원 위치에 '-1'을 넣으면 어떻게 재구조화가 되는지 살펴보겠습니다.
총 12개의 원소가 들어있는 배열 x에 대해서 x.reshape(-1, 정수) 를 해주면 '열(column)' 차원의 '정수'에 따라서 12개의 원소가 빠짐없이 배치될 수 있도록 '-1'이 들어가 있는 '행(row)' 의 개수가 가변적으로 정해짐을 알 수 있습니다.
x.reshape(-1, 1) => shape(12,1) |
x.reshape(-1, 2) => shape(6, 2) |
x.reshape(-1, 3) => shape(4, 3) |
x.reshape(-1, 4) => shape(3, 4) |
In [5]: x.reshape(-1, 1) Out[5]: array([[ 0], [ 1], [ 2], [ 3], [ 4], [ 5], [ 6], [ 7], [ 8], [ 9], [10],
[11]]) |
In [6]: x.reshape(-1, 2) Out[6]: array([[ 0, 1], [ 2, 3], [ 4, 5], [ 6, 7], [ 8, 9], [10, 11]]) |
In [7]: x.reshape(-1, 3) Out[7]: array([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11]]) |
In [8]: x.reshape(-1, 4) Out[8]: array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) |
(2) reshape(정수, -1) 의 열(column) 위치에 '-1'이 들어있을 경우 |
다음으로 reshape()의 열(column) 위치에 '-1'을 넣으면 어떻게 재구조화되는지 살펴보겠습니다.
x의 총 원소 12개가 모두 배열될 수 있도록 행(row)의 정수가 정해지면, 이에 따라서 '-1'이 들어있는 열(column)의 개수가 정해짐을 알 수 있습니다.
즉, 행이나 열의 특정 차원을 기준으로 재배열하고 싶은 행이나 열의 개수가 있으면 나머지 차원의 개수는 '-1'로 해두면 알아서 자동으로 재배열을 해주니 편리한 기능이라고 하겠습니다.
x.reshape(1, -1) => shape(1, 12) |
In [9]: x.reshape(1, -1) Out[9]: array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]])
|
x.reshape(2, -1) => shape(2, 6) |
In [10]: x.reshape(2, -1) Out[10]: array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11]]) |
x.reshape(3, -1) => shape(3, 4) |
In [11]: x.reshape(3, -1) Out[11]: array([[ 0, 1, 2, 3], [ 4, 5, 6, 7],
[ 8, 9, 10, 11]]) |
x.reshape(4, -1) => shape(4, 3) |
In [12]: x.reshape(4, -1) Out[12]: array([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8],
[ 9, 10, 11]]) |
(3) reshape(-1) 인 경우 |
x.reshape(-1)은 x.reshape(1, -1)과 같이 1차원 배열을 반환합니다.
x.reshape(-1) |
In [13]: x.reshape(-1)
Out[13]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) |
x.reshape(1, -1) |
x.reshape(1, -1) Out[14]: array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]]) |
(4) ValueError: cannot reshape array of size 12 into shape (5) |
reshape(-1, 정수) 또는 reshape(정수, -1) 메소드가 제대로 작동하기 위해서는 한가지 조건이 있는데요, 원래의 배열에 있는 원소가 재구조화 혹은 재배열 되려는 배열의 차원에 빠짐없이 분배가 될 수 있어야 한다는 점입니다.
가령, 위의 (1), (2), (3)번 예에서는 12개의 원소로 구성된 x배열을 (1, 12), (2, 6), (3, 4), (4, 3) 으로 재배열했었습니다. 하지만 아래의 ValueError 가 난 것처럼 12개의 원소로 구성된 원래의 배열 x에 대해 x.reshape(-1, 5) 혹은 x.reshape(7, -1) 로 재구조화하려고 하면 서로 호환이 안되기 때문에 ValueError가 난 것입니다.
In [15]: x.reshape(-1, 5) Traceback (most recent call last): File "<ipython-input-15-3341ca33497d>", line 1, in <module> x.reshape(-1, 5) ValueError: cannot reshape array of size 12 into shape (5)
In [16]: x.reshape(7, -1) Traceback (most recent call last): File "<ipython-input-16-c8e97ae7c9bc>", line 1, in <module> x.reshape(7, -1) ValueError: cannot reshape array of size 12 into shape (7,newaxis)
|
(5) ValueError: can only specify one unknown dimension |
reshape(-1, -1)은 행, 열 어느 차원도 정해주지 않았으므로 ValueError 가 발생합니다.
In [17]: x.reshape(-1, -1) Traceback (most recent call last): File "<ipython-input-17-8142d87a8f95>", line 1, in <module> x.reshape(-1, -1)
ValueError: can only specify one unknown dimension
|
많은 도움이 되었기를 바랍니다.
이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. ^^