[Python] Pandas를 활용해 downcast로 메모리 부담 줄이기
Pandas의 to_numeric 함수를 이용해 메모리 용량 줄이기
✔️ downcast 란?
pandas 의 to_numeric
함수에서 선택적으로 사용할 수 있는 파라미터이다.
정형 데이터에 data type를 지정해 가장 작은 버전으로 낮춰 메모리를 절약할 수 있다.
데이터는 컴퓨터 RAM 용량만큼 불러올 수 있는데, 대용량 데이터를 불러와서 분석하거나 모델을 만들기 위해서는 메모리를 효율적으로 사용할 수 있어야 한다.
downcast가 필요한 이유는 메모리 사용량을 절약해 더 많은 데이터를 불러오고 더 많은 데이터를 분석하기 위해서이다.
(1) data type
Data type | Description | |
---|---|---|
0 | bool | Boolean (True or False) stored as a byte |
1 | int | Platform integer (normally either int32 or int64) |
2 | int8 | Byte (-128 to 127) |
3 | int16 | Integer (-32768 to 32767) |
4 | int32 | Integer (-2147483648 to 2147483647) |
5 | int64 | Integer (-9223372036854775808 to 9223372036854775807) |
6 | uint8 | Unsigned integer (0 to 255) |
7 | uint16 | Unsigned integer (0 to 65535) |
8 | uint32 | Unsigned integer (0 to 4294967295) |
9 | uint64 | Unsigned integer (0 to 18446744073709551615) |
10 | float | Shorthand for float64. |
11 | float16 | Half precision float: sign bit, 5 bits exponent, 10 bits mantissa |
12 | float32 | Single precision float: sign bit, 8 bits exponent, 23 bits mantissa |
13 | float64 | Double precision float: sign bit, 11 bits exponent, 52 bits mantissa |
14 | complex | Shorthand for complex128. |
15 | complex64 | Complex number, represented by two 32-bit floats |
16 | complex128 | Complex number, represented by two 64-bit floats |
✔️ downcast 적용
- 실습으로 이해하기
- Dataset : Kaggle 타이타닉 - train.csv
- 👉 데이터 보러가기
(1) 데이터 기본구조
Survived
,Pclass
,SibSp
,Parch
컬럼은 모두 최솟값이 0 이상, 최댓값이 10 이하로 구성되어있다.- 하지만 dtype을 보면 모두 int64
- 즉, RAM이 불필요하게 많이 쓰이고 있다는 뜻
Age
,Fare
컬럼도 기술통계값을 보면 float64로 사용하기엔 적절하지 않다.
import pandas as pd
df = pd.read_csv("data/titanic/train.csv", index_col="PassengerId")
# downcast 전 총 메모리 사용량을 KB 기준으로 before_dc 변수에 저장함
before_dc = df.memory_usage().sum() / 1024
# 데이터프레임의 수치형 변수에 대한 기술통계값 확인
display(df.describe())
# 데이터프레임의 기본정보 확인
df.info()
(2) 다운캐스팅(downcasting)
- 데이터타입의 버전을 낮추는 일은 함수를 만들어서 각 컬럼별로 적용해보았다.
- 정형 데이터의 dtype이 int/float로 구성되어 있어 dtype_downcast 함수에 int/float의 경우만 넣었다.
def dtype_downcast(data):
# 데이터프레임의 전체 컬럼에 대해 downcast 적용
for col in df.columns:
# 컬럼별 데이터타입을 dtype_name 변수에 할당
dtype_name = df[col].dtypes.name
# dtype이 int로 시작하는 경우
if dtype_name.startswith("int"):
# 0이상의 값만 가지는 컬럼인 경우
if df[col].min() >= 0:
# 0과 양의 정수만 포함하는 uint로 전환
df[col] = pd.to_numeric(df[col], downcast="unsigned")
# 0이하의 값도 포함하는 컬럼인 경우
else:
# 음의 정수, 0, 양의 정수를 포함하는 int로 전환
df[col] = pd.to_numeric(df[col], downcast="integer")
# dtype이 float로 시작하는 경우
elif dtype_name.startswith("float"):
# 가장 작은 버전의 float 타입으로 전환
df[col] = pd.to_numeric(df[col], downcast="float")
dtype_downcast(df)
# downcast 후 총 메모리 사용량을 KB 기준으로 after_dc 변수에 저장함
after_dc = df.memory_usage().sum() / 1024
(3) 결과 모니터링
>>> print(f"downcast 전 : {before_downcast:.1f}+ KB")
>>> print(f"downcast 후 : {after_downcast:.1f}KB")
>>> print(f"절약한 총 메모리 사용량 : {(before_downcast - after_downcast):.1f}KB")
downcast 전 : 83.5+ KB
downcast 후 : 52.2+ KB
절약한 총 메모리 사용량 : 31.3+ KB
✔️ 마치며
Kaggle의 train.csv 파일의 데이터를 불러왔을 때, 메모리 사용량을 보면 83.5 +KB 인데 정형 데이터를 pandas의 to_numeric
함수를 사용하여 낮은 버전의 dtype으로 바꿈으로써 메모리 사용량을 52.2 +KB로 약 63% 줄여보았다.
정형 데이터의 범위에 비해 dtype으로 표현할 수 있는 숫자 범위가 크다면 downcast로 데이터 사용량을 절약할 수 있다.
✔️ Reference
- [멋쟁이사자처럼 AI SCHOOL] 박조은 강사님 강의자료
- Github by rougier, numpy-tutorial
- pandas 공식문서, pandas.to_numeric
- 벨로그 by JinBaek, 메모리와 데이터 타입
- 네이버블로그 by apple, [Python][Pandas] Big Data 메모리 사용량 줄이기(MemoryError)
- 티스토리 by Data_Pistachio, 판다스 - 자료형 변환 : astype, pd.to_numeric
- 티스토리 by 꾸준희, [Python] 자료형(type) 확인과 numpy 데이터 형변환
- 티스토리 by ‘내’멋대로해라, 변수의 기본형 데이터 타입 사용시 (효율성, 성능중시)
- 티스토리 by All I Need Is Data., [Python] 정형데이터 용량 줄이는 함수 소개 (연속형, 이산형, 문자형)
👩🏻💻개인 공부 기록용 블로그입니다
오류나 틀린 부분이 있을 경우 댓글 혹은 메일로 따끔하게 지적해주시면 감사하겠습니다.
댓글남기기