sklearn을 사용하다 보면 제목과 같은 에러 메시지를 종종 볼 수 있다. 다행히 개발자분들 께서 친절히 에러 메시지에 해결책을 써두고는 한다:
from sklearn.impute import SimpleImputer
imp = SimpleImputer()
imp.fit_transform([1,2,3])
ValueError: Expected 2D array, got 1D array instead:
array=[1. 2. 3.].
Reshape your data either using array.reshape(-1, 1) if your data has a single feature or array.reshape(1, -1) if it contains a single sample.
fit_transform이 2d array를 받아야 하나 1d array (이 경우는 단순한 list)를 집어 넣어서 그런건데, 본인의 상황에 따라 맞는 모양의 2d array로 바꿔주면 해결 할 수 있다.
근데 왜?
첫줄에서 말했다시피 해결책은 에러에 써져 있는데... 왜 이런 글을 쓰게 되었냐면,
첫번째로 위의 예시와 같이 list를 넣었다면 [1,2,3].reshape(-1, 1) 으로 해결할 수가 없다.
reshape은 numpy.ndarray의 메소드이므로, 뭐야 이거 안되는데 라는 상황으로 갈 수 있다.
둘째로는, 이런식으로 해결책을 제공하는 경우에는 잠깐 코드를 수정하고 넘어 가버리는 경우가 대다수고, 실질적으로 무엇이 왜 잘 못 되었는가 또는 numpy.reshape이 왜 문제를 해결하는가 등에 대한 추가적인 고찰이 전혀 없을 수 있다. reshape인데 (-1, 1) 또는 (1, -1)은 무엇인가, 그런 것들을 오늘 짚고 넘어가 보려 한다.
원론적인 이슈
일단 기본적으로, sklearn은 거의 모든 경우에서 자신의 인풋 X가 2d로 들어 올 것으로 상정하고 있다. 당장 예시의 sklearn.impute.SimpleImputer의 설명만 보아도 출처:
X : {array-like, sparse matrix}, shape (n_samples, n_features)
Input data, where n_samples is the number of samples and n_features is the number of features.
n_samples x n_features로 이루어지는 array를 기대하고 있는것을 알 수 있다.
근데 여기다가 1d array 또는 list 를 주면? 이게 하나의 feature에 여러개의 samples이 있는건지, 여러개의 features에 하나씩의 sample이 있는건지 알 수가 없다. 그러니 자꾸 당신에게 되묻는거다, 친절한 설명과 함께.
numpy 해결책
에러 메시지를 천천히 읽어 봤다면 (또는 이 글을 열심히 읽었다면) 에러에 해결책이 존재한다. 만약 넣었던 X가 numpy.ndarray라면[^1] 바로 자신의 상황에 맞게 X.reshape(-1, 1)또는 X.reshape(1, -1)로 넣어주면 된다. reshape자체는 in-place 작업이 아니므로, 새로 변수 지정을 해주거나 fit에 바로 넣어주도록 한다. 무슨 말이냐고?
그렇지만 numpy가 누군가. 그렇게 호락호락한 라이브러리가 아니다. 당연히 독립함수도 있다. numpy.reshape을 쓰면 리스트도 얼마든지 바꿔진다!
import numpy as np
np.reshape([1,2,3], (-1, 1))
array([[1],
[2],
[3]])
혹시 numpy.reshape으로도 안바뀌는 데이터가 있다면 제보를 부탁한다.
번외: (-1, 1)? (1, -1)?
먼저 sklearn의 설명을 다시 한번 보자.
X : {array-like, sparse matrix}, shape (n_samples, n_features)
Input data, where n_samples is the number of samples and n_features is the number of features.
우리의 목표는 shape이 (int, int)로 이루어진 2Darray를 만드는 것이다. 이 작업을 해주는 녀석이 numpy.reshape인데, 여기에 (-1, 1) 또는 (1, -1)을 넣는것이 해결책이였다. 근데 이게 뭐냐고..?
newshape : int or tuple of ints
The new shape should be compatible with the original shape. If an integer, then the result will be a 1-D array of that length. One shape dimension can be -1. In this case, the value is inferred from the length of the array and remaining dimensions.
numpy.reshape으로 변환하려는 녀석의 새로운 shape을 지정해 준다!
물론 음수가 아니라 모두 양수로도 가능하다 (3,2) 라던지. 그러나 이 경우에는, newshape[0] * newshape[1]이 기존에 가지고 있는 데이터의 갯수와 일치하여야 한다. 미리 알고 진행하면 좋지만, 그렇지 않을 수도 있으니, -1이 등장하게 된다.
-1은, 다른 newshape의 element들에 따라 결정되는데, (-1,1)이라고 하는것은, feature의 갯수는 1개이니, 나머지는 알아서 정해라, 정도로 해석될 수 있다. 이에 따라 우리의 (3,) array가, (3, 1)로 reshape되며, sklearn에서 바라던 2D로 정상적으로 바뀐다는 것을 알 수 있다.
[debugging] Expected 2D array, got 1D array instead
sklearn
을 사용하다 보면 제목과 같은 에러 메시지를 종종 볼 수 있다. 다행히 개발자분들 께서 친절히 에러 메시지에 해결책을 써두고는 한다:fit_transform
이 2darray
를 받아야 하나 1darray
(이 경우는 단순한list
)를 집어 넣어서 그런건데, 본인의 상황에 따라 맞는 모양의 2d array로 바꿔주면 해결 할 수 있다.근데 왜?
첫줄에서 말했다시피 해결책은 에러에 써져 있는데... 왜 이런 글을 쓰게 되었냐면,
첫번째로 위의 예시와 같이
list
를 넣었다면[1,2,3].reshape(-1, 1)
으로 해결할 수가 없다.reshape
은numpy.ndarray
의 메소드이므로, 뭐야 이거 안되는데 라는 상황으로 갈 수 있다.둘째로는, 이런식으로 해결책을 제공하는 경우에는 잠깐 코드를 수정하고 넘어 가버리는 경우가 대다수고, 실질적으로 무엇이 왜 잘 못 되었는가 또는
numpy.reshape
이 왜 문제를 해결하는가 등에 대한 추가적인 고찰이 전혀 없을 수 있다.reshape
인데(-1, 1)
또는(1, -1)
은 무엇인가, 그런 것들을 오늘 짚고 넘어가 보려 한다.원론적인 이슈
일단 기본적으로,
sklearn
은 거의 모든 경우에서 자신의 인풋X
가 2d로 들어 올 것으로 상정하고 있다. 당장 예시의sklearn.impute.SimpleImputer
의 설명만 보아도 출처:n_samples x n_features로 이루어지는
array
를 기대하고 있는것을 알 수 있다.근데 여기다가 1d
array
또는list
를 주면? 이게 하나의 feature에 여러개의 samples이 있는건지, 여러개의 features에 하나씩의 sample이 있는건지 알 수가 없다. 그러니 자꾸 당신에게 되묻는거다, 친절한 설명과 함께.numpy
해결책에러 메시지를 천천히 읽어 봤다면 (또는 이 글을 열심히 읽었다면) 에러에 해결책이 존재한다. 만약 넣었던
X
가numpy.ndarray
라면[^1] 바로 자신의 상황에 맞게X.reshape(-1, 1)
또는X.reshape(1, -1)
로 넣어주면 된다.reshape
자체는 in-place 작업이 아니므로, 새로 변수 지정을 해주거나fit
에 바로 넣어주도록 한다. 무슨 말이냐고?위의 상황을 보면,
reshape
을 하긴 했는데, 정작 결과물을 재지정 또는 신규지정을 안해주니 똑같은 에러가 반겨준다. (의외로 이런 질문이 자주 보인다.)재지정해주면 에러가 싹 사라진다.
근데 전
list
인데요..list.reshape
은 당연히 존재하지 않으므로 위의 해결책으로는 할 수 없다.그렇지만
numpy
가 누군가. 그렇게 호락호락한 라이브러리가 아니다. 당연히 독립함수도 있다.numpy.reshape
을 쓰면 리스트도 얼마든지 바꿔진다!혹시
numpy.reshape
으로도 안바뀌는 데이터가 있다면 제보를 부탁한다.번외: (-1, 1)? (1, -1)?
먼저
sklearn
의 설명을 다시 한번 보자.우리의 목표는 shape이 (int, int)로 이루어진 2D
array
를 만드는 것이다. 이 작업을 해주는 녀석이numpy.reshape
인데, 여기에(-1, 1)
또는(1, -1)
을 넣는것이 해결책이였다. 근데 이게 뭐냐고..?numpy.reshape
으로 변환하려는 녀석의 새로운 shape을 지정해 준다!물론 음수가 아니라 모두 양수로도 가능하다
(3,2)
라던지. 그러나 이 경우에는,newshape[0] * newshape[1]
이 기존에 가지고 있는 데이터의 갯수와 일치하여야 한다. 미리 알고 진행하면 좋지만, 그렇지 않을 수도 있으니,-1
이 등장하게 된다.-1
은, 다른 newshape의 element들에 따라 결정되는데,(-1,1)
이라고 하는것은, feature의 갯수는 1개이니, 나머지는 알아서 정해라, 정도로 해석될 수 있다. 이에 따라 우리의(3,)
array가,(3, 1)
로reshape
되며,sklearn
에서 바라던 2D로 정상적으로 바뀐다는 것을 알 수 있다.[^1]: 헷갈린다면
type(X)
로 확인하자.'Python > Scikit-Learn' 카테고리의 다른 글