목 차
1. 들어가며
2. 에러 발생 과정
1) 데이터프레임 형태로 전환 과정
2) 딕셔너리의 value 값을 업데이트 한다.
3) 데이터프레임 만들기 → 여기서 에러 발생
3. 에러 해결 방법
1) for문으로 받는 최초 데이터는 head(2)를 이용
2) for문으로 받는 2번째 데이터부터는 tail(1)을 이용
3) CSV에 저장하기
4. 마치며
1. 들어가며
바이비트로 비트코인의 1분봉 과거데이터를 데이터프레임 형태로 만드는 과정에서
아래의 에러가 발생하였다.
- 오류 내용 : ValueError: If using all scalar values, you must pass an index
"모든 스칼라 값을 사용한다면, 인덱스를 전달하여야 한다"는 내용이다.
오류 내용이 너무 어렵다. @.@
그냥 인덱스 설정하라고 하면 되는데 말이다.
2. 에러 발생 과정
1) 데이터프레임 형태로 전환 과정
아래 <코드>는 일부 발췌한 내용이다.
바이비트API를 통해 받아온 5개 데이터를 데이터프레임 형태로 만들었다.
* 5개 데이터는 data, open, high, low, close이다.
data = resp['result'][0]['open_time']
open = resp['result'][0]['open']
high = resp['result'][0] ['high']
low = resp['result'][0]['low']
close = resp['result'][0]['close']
data = dt.datetime.fromtimestamp(data)
minute_coin = {'data': [], 'open': [], 'high': [], 'low': [], 'close': []}
2) 딕셔너리의 value 값을 업데이트 한다.
바로 위의 <코드>와 연결되는 부분이다.
minute_coin = {'data' : [ ], ....... }
①key ②value
minute_coin는 딕셔너리 형태이며,
각각의 keys에 대응하는 value값은 공란인데,
2줄~5줄의 내용으로 values 대체(갱신)한다.
→ 즉 바뀌는 쪽은 key값(①)이 아니라, value값(②)이다.
위의 대체(갱신)된 내용은 df3에서 데이터프레임하는데, 여기서 에러가 발생한다.
minute_coin = {'data': [], 'open': [], 'high': [], 'low': [], 'close': []}
minute_coin['data'] = data
minute_coin['open'] = open
minute_coin['high'] = high
minute_coin['low'] = low
minute_coin['close'] = close
df3 = pd.DataFrame(minute_coin, columns=['data', 'open', 'high', 'low', 'close'])
df3 = df3.head(2)
df4 = df3.tail(1)
3) 데이터프레임 만들기 → 여기서 에러 발생
minute_coin의 형태는 딕셔너리이며,
각각의 요소들은 "key : value"로 매칭되어 있다.
딕셔너리 형태를 데이터프레임으로 바꾸기 위해서는
pandas.DataFrame(딕셔너리 자료, index 설정, columns 설정, ....) 형태로 바꿀 수 있다.
- pd.DataFrame(딕셔너리 자료, index=['data'], columns['open', 'high', 'low', 'close']
위와 같이 인덱스 설정을 잘못 설정하면, 아래와 같은 화면이 나온다.
data를 인덱스로 설정을 하니, 엑셀의 2번째 줄에서
for문의 1회차 실행시 인덱스 data가 설정되고,
2회차 실행시 데이터가 붙은데,
2개 데이터가 2번줄에서 겹쳐져서, 엑셀에 기록된다.
그렇다고 인덱스 설정을 없애면, 다시 오류 메시지가 나온다. ㅠㅠ
ValueError: If using all scalar values, you must pass an index
3. 에러 해결 방법
pd.DataFrame(딕셔너리 자료, index, columns)에서 index를 설정해주니
오류는 해결되었다.
여기서는 다른 이야기를 하고 싶다.
데이터프레임을 만드는 과정에서 인덱스(index)를 반드시 설정해 주어야 한다면,
인덱스를 설정하되, 향후 출력이 안되게 하면 되지 않을까?
아래 <코드>에서 index는 data로 설정하였고, columns는 data~close로 설정하였다.
1) for문으로 받는 최초 데이터는 head(2)를 이용
여기서 중요하다.
df3에 담았던 데이터프레임 자료의 상단 2개만 축출하게 변경하자.(head(2))
2) for문으로 받는 2번째 데이터부터는 tail(1)을 이용
→ 구분(그림3의 1번째 줄)을 제외하고 순수하게 데이터만 가져온다.(df4로 설정)
3) CSV에 저장하기
① 파일이 없으면 df3(그림3의 1~2줄)를 CSV 파일에 넣어라!
여기서 위에서 설정한 index['data']를 false를 한다.
→ 즉, 데이터프레임에서 설정한 data 인덱스를, 여기서는 false로 해서
CSV에 기록되지 않게 한다.
② 파일이 있으면 DF4(그림3의 2줄~)을 CSV 파일에 넣어라
여기서도 위에서 설정한 index['data']를 false를 한다.
※ 이유는 모르겠지만, 바이비트API는 00:00분의 정각은 날짜만 제공한다.
참고만 하자.
df3 = pd.DataFrame(minute_coin, index=['data'], columns=['data', 'open', 'high', 'low', 'close'])
df3 = df3.head(2)
df4 = df3.tail(1)
dir = r"C:\Users\ ... \bitcoin_minute.csv"
if os.path.exists(dir):
df4.to_csv(dir, mode = "a", index=False, header=False)
else:
df3.to_csv(dir, mode = "w", index=False)
4. 마치며
딕셔너리 자료를 데이터프레임 자료로 만드는 과정에서
발생하는 오류를 알아보았다.
물론 데이터프레임에서 인덱스를 넣지않는 방법이 가장 좋았을거 같지만,
필자가 진행하는 코드는 데이터프레임으로 만들어서 CSV파일로 보내는 게 최종목적이었다.
오류는 수시로 발생한다.
발생한 오류에 대해 속상한 마음만 가지면 해결이 안된다.
잠깐 바람 쐬고나서,
천천히 오류를 해결해 보는 습관을 가지도록 노력하자.