본문 바로가기
Artificial Intelligence/60. Python

[PYTHON] 빅데이터 처리를 위한 Pandas 메모리 70% 절약 방법과 Dtype 최적화 차이 해결

by Papa Martino V 2026. 2. 22.
728x90

Pandas 메모리
Pandas 메모리

 

데이터 분석가와 소프트웨어 엔지니어에게 Pandas는 축복과도 같은 라이브러리지만, 대용량 데이터를 다룰 때는 '메모리 킬러'로 돌변하곤 합니다. 파이썬의 동적 타이핑 특성상 Pandas는 데이터를 읽어올 때 안전을 위해 필요 이상의 메모리를 할당하는 경향이 있습니다. 본 가이드에서는 Dtype(데이터 타입) 최적화를 통해 메모리 사용량을 획기적으로 줄이는 전문적인 방법과 데이터 손실 없이 최적화하는 핵심 전략을 다룹니다.


1. 왜 Pandas 메모리 최적화가 중요한가?

로컬 환경에서 8GB 이상의 CSV 파일을 로드하려고 시도하다 MemoryError를 마주한 적이 있다면, 메모리 관리의 절실함을 느끼셨을 겁니다. Pandas는 기본적으로 정수형 데이터에 int64, 실수형에 float64를 할당합니다. 하지만 우리 데이터가 0에서 100 사이의 숫자만 포함한다면, 8바이트(64비트)가 아닌 1바이트(8비트)만으로도 충분히 표현 가능합니다. 이러한 차이를 해결하는 것이 최적화의 핵심입니다.


2. 데이터 타입별 최적화 전략 및 메모리 감소 차이 비교

각 데이터 타입이 메모리에 미치는 영향과 최적화 후의 변화를 비교 분석한 표입니다.

데이터 유형 기본 Dtype (Default) 최적화 Dtype (Optimized) 메모리 절감 효과
정수 (Integer) int64 (8 bytes) int8 / int16 (1~2 bytes) 최대 87.5% 감소
실수 (Float) float64 (8 bytes) float32 (4 bytes) 50% 감소
문자열 (Object) object (가변 메모리) category (포인터 방식) 중복 데이터 많을수록 극대화 (90%+)
불리언 (Boolean) object (NaN 포함 시) boolean (Nullable) 상당 수준 감소

3. [Sample Example] 실전 Dtype 최적화 구현 방법

아래 코드는 데이터프레임의 각 컬럼을 검사하여 수치 범위에 맞는 최소한의 비트 수로 타입을 변경하는 자동화 스크립트 예시입니다.


import pandas as pd
import numpy as np

def optimize_dtypes(df):
    start_mem = df.memory_usage().sum() / 1024**2
    print(f"초기 메모리 사용량: {start_mem:.2f} MB")

    for col in df.columns:
        col_type = df[col].dtype

        if col_type != object:
            c_min = df[col].min()
            c_max = df[col].max()
            
            # 정수형 최적화
            if str(col_type)[:3] == 'int':
                if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:
                    df[col] = df[col].astype(np.int8)
                elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:
                    df[col] = df[col].astype(np.int16)
                elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:
                    df[col] = df[col].astype(np.int32)
            # 실수형 최적화
            else:
                if c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:
                    df[col] = df[col].astype(np.float32)
        else:
            # 문자열 데이터 중 고유값이 적은 경우 카테고리로 변환
            num_unique = len(df[col].unique())
            num_total = len(df[col])
            if num_unique / num_total < 0.5:
                df[col] = df[col].astype('category')

    end_mem = df.memory_usage().sum() / 1024**2
    print(f"최적화 후 메모리 사용량: {end_mem:.2f} MB")
    print(f"절약된 비율: {100 * (start_mem - end_mem) / start_mem:.2f}%")
    return df

# 가상의 대용량 데이터프레임 생성
data = {
    'age': np.random.randint(0, 100, size=100000),
    'score': np.random.random(size=100000),
    'city': ['Seoul', 'Busan', 'Incheon', 'Daegu'] * 25000
}
df = pd.DataFrame(data)
optimized_df = optimize_dtypes(df)

4. 고급 최적화 팁: 범주형 데이터(Category)의 힘

파이썬의 object 타입은 파이썬 객체에 대한 포인터를 저장하기 때문에 메모리 소모가 극심합니다. 성별, 도시 이름, 혈액형 등 중복이 잦은 문자열 데이터category 타입으로 변환하면, 내부적으로는 정수 인덱스만 저장하고 실제 문자열은 한 번만 저장하게 되어 메모리 효율이 비약적으로 상승합니다.

주의사항: 고유값(Unique values)이 행 수에 비해 너무 많은 경우에는 오히려 category 타입이 메모리를 더 많이 사용할 수 있으므로 위 예제 코드처럼 비율을 체크하는 것이 해결 방법입니다.

5. 데이터 로드 시점에서의 선제적 대응

이미 메모리에 로드된 후에 최적화하는 것도 방법이지만, pd.read_csv() 함수를 호출할 때 dtype 인자를 미리 전달하는 것이 가장 효율적입니다. 이는 데이터를 읽는 과정에서 발생하는 일시적인 메모리 피크(Peak)를 방지해 줍니다.

  • low_memory=False 설정으로 타입 추론의 정확도를 높이기
  • usecols를 사용하여 필요한 컬럼만 선택적으로 로드하기
  • chunksize를 활용하여 데이터를 분할 처리하기

6. 결론

Pandas의 메모리 효율성을 높이는 과정은 단순한 성능 최적화를 넘어, 한정된 자원 내에서 처리할 수 있는 데이터의 한계를 넓히는 중요한 작업입니다. 정수형과 실수형의 범위를 파악하여 적절한 비트수를 할당하고, 반복되는 문자열은 카테고리화 하는 전략을 통해 여러분의 파이썬 분석 환경을 쾌적하게 유지해 보시기 바랍니다.


내용의 출처 및 참고 자료

  • Pandas Official Documentation: Enhancing Performance - Memory Usage.
  • Real Python: Memory Management in Python.
  • High Performance Python by Micha Gorelick and Ian Ozsvald.
  • Numpy Documentation: Data Types (Dtypes) and bit precision.
728x90