Python DataFrame 메모리 사용량 줄이는 방법 - downcasting
kaggle의 Predict Future Sales 대회에 참여하던 중 colab을 사용하다 불편한 점을 하나 느끼게 되었습니다. 기존 train dataset에 수많은 column들을 새로 추가하다 보니 데이터 전처리 작업이 점점 느려지고 model을 fit 할 때도 종종 터지는 일이 발생하였습니다. 그래서 효율적인 메모리 사용에 대해 궁금하였고, 알게 된 점을 아래에 공유하려고 합니다.
데이터는 위에서 말한 대회의 train dataset을 기준으로 설명해보겠습니다.
간단하게 위 dataset을 설명하자면, 특정 매장에 특정 물건을 판 기록을 나타낸 데이터입니다. 날짜, 매장 고유 아이디, 아이템 고유 아이디, 가격, 수량이 표시되어 있고 date_block_num은 2013년 1월을 0으로 시작하여 달이 바뀔 때마다 1씩 증가하는 데이터입니다. 그리고 shape을 통해 2935849개의 row를 가지고 있고 column은 총 6개임을 알 수 있습니다.
train dataset이 위와 같이 구성되었음을 알 수 있었고 각 column의 type을 변경해보며 memory usage의 변화를 살펴보겠습니다. (이러한 방법을 downcasting 이라고 합니다)
일단 date column을 제외한 모든 수치형 column들의 data type을 변경해보겠습니다. 변경을 하기 위해서는 각 column data들의 범위를 알아야 하기 때문에 아래 사진처럼 구해줍니다.
주의할 점은 data의 범위에 따라 type을 줄여주되 연산이 들어가는 column이라면 범위를 넓게 잡아주는 것이 좋습니다.
그래서 item_price, item_cnt_day column은 float32로 많이 줄여주지는 않았습니다.
train = train.astype({"date_block_num":"int8", "shop_id":"int8", "item_id":"int16",
"item_price":"float32", "item_cnt_day":"float32"})
수치형 column들의 data type을 변경한 후 memory usage를 확인한 결과는 아래와 같습니다.
대략 26% 정도 memory 사용을 줄였음을 알 수 있었습니다. 남은 date column을 object type에서 datetime type으로 한 번 바꿔보겠습니다.
import pandas as pd
train["date"] = pd.to_datetime(train["date"], format="%d.%m.%Y")
date column의 data type을 변경한 후 memory usage를 확인한 결과는 아래와 같습니다.
앞에서 수치형 column들 여러개를 줄인 것보다 굉장히 크게 줄어드는 것을 확인할 수 있었고 date column 하나만 줄였을 때 75% 정도 memory usage를 줄일 수 있었습니다.
string이 들어간 object type을 category type으로 변경해주거나, 위처럼 datetime type으로 변경해준다면 memory 사용량을 많이 절약할 수 있음을 알 수 있었습니다.