본문 바로가기

정보/오류

[Python] ValueError: If using all scalar values, you must pass an index 간단 해결 방법

위의 오류가 떴다면 당신은 딕셔너리를 데이터프레임으로 만드는 과정에서 오류가 떴을 가능성이 높다.

 

오류의 내용은 데이터프레임의 모든 값이 스칼라 형태일 경우 인덱스 값을 입력해야 한다는 것이다.

 

스칼라1차원 데이터를 의미한다. 리스트로 감싸주면 2차원 데이터(벡터), 리스트 안에 또 리스트로 감싸주면 3차원 데이터(행렬)가 된다.

 

해결하기 위해서는 스칼라 형태를 바꾸든, 인덱스 값을 입력하든 하면 된다. 딕셔너리를 리스트로 감싸는 방법도 있다.

 

 

해결 방법


1. 인덱스 값 입력

>>> dic = {"A": "a", "B": "b", "C": "c", "D": "d"}
>>> pd.DataFrame(dic, index=[0])
   A  B  C  D
0  a  b  c  d

오류 메시지의 뜻대로 인덱스를 입력해 준다. 인덱스에는 리스트 안에 숫자형이든 문자형이든 아무거나 넣어주면 된다.

 

2. 스칼라 형태 변경

>>> dic = {"A": ["a"], "B": ["b"], "C": ["c"], "D": ["d"]}
>>> pd.DataFrame(dic)
   A  B  C  D
0  a  b  c  d

데이터프레임의 값을 스칼라에서 벡터(리스트) 형태로 바꾸어준다.

 

여기서 재밌는 점은 위의 오류 메시지에도 나와있듯이 모든 값이 스칼라일 경우에 에러가 나는 것이기 때문에 하나의 값만 바꾸어 줘도 된다.

>>> dic = {"A": "a", "B": ["b"], "C": "c", "D": "d"}
>>> pd.DataFrame(dic)
   A  B  C  D
0  a  b  c  d

 

3. 딕셔너리를 리스트로 감싸기

>>> dic = {"A": "a", "B": "b", "C": "c", "D": "d"}
>>> pd.DataFrame([dic])
   A  B  C  D
0  a  b  c  d

사실 제일 쉬운 방법이다. 이것만 알아도 된다. 딕셔너리를 리스트로 감싸주면 된다.

 

 

오류 발생 원인


왜 이런 오류를 나타나게 하는지 곰곰이 생각해보고 여러 실험을 해보았다.

 

그리고, 해답을 찾았다.

>>> dic = {"A": "a", "B": ["b","c"], "C": "c", "D": ["d", "f"]}
>>> pd.DataFrame(dic)
   A  B  C  D
0  a  b  c  d
1  a  c  c  f

위에서 보다시피, 스칼라 값이 섞여있더라도 모든 값이 스칼라인 것만 아니라면 오류가 나타나지 않는다.

 

데이터프레임 생성 함수에 딕셔너리를 넣게 되면 행의 길이는 value의 제일 긴 값에 맞춰진다.

 

위에서는 "B"와 "D"의 value가 두 개의 데이터로 이루어져있기 때문에 행이 2개인 데이터프레임이 생성된다.

 

그러면 "A"와 "C"의 데이터는? 스칼라 값이 복제되어 행의 길이를 맞춰준다.

 

따라서 모든 값이 스칼라인 경우에 데이터프레임은 행의 길이를 예측할 수 없다.

 

스칼라 값은 데이터프레임의 행의 길이에 맞춰 복제되는 성격을 갖기 때문이다.

 

주의할 점은 리스트로 감싸준 데이터의 개수는 같아야 한다.

>>> dic = {"A": "a", "B": ["b","c","d"], "C": "c", "D": ["d", "f"]}
>>> pd.DataFrame(dic)

예를 들어 이렇게 "B"와 "D"의 데이터의 길이가 같지 않으면 오류가 발생한다.

 

값이 복제되는 것은 스칼라인 경우만 가능하다.