SK플래닛 ai활용 데이터엔지니어 과정 2기/데이터 처리

데이터 처리 3 - polars

dev-lee 2026. 5. 14. 15:51

1. 개요

1.1 데이터 처리 시 고려사항

  • 형태 — 정형/반정형/비정형
  • 규모 — 데이터 볼륨 (MB / GB / TB)
  • 환경 — 싱글 머신 vs 분산 환경
  • 가용 메모리 — 처리 가능한 한계 결정

1.2 도구별 특징 비교

라이브러리  특징  베이스 언어  데이터 규모  현업 사용
numpy ndarray 중심 수치 계산, 분석/처리의 근간 C 기반 연산 소~중규모
pandas Series/DataFrame, 메모리 일괄 로드 Python+Cython+C (Single Core) 중규모 (~수 GB) 많이사용
polars 최적화, 지연처리, 스트리밍, 병렬처리 Rust / Apache Arrow 대규모 (~수십 GB) 증가추세
spark RDD/DataFrame/DataSet, 분산 처리 Scala/Java/PySpark/RSpark 초대규모 (~TB 이상) 많이사용

데이터가 3GB이고 머신 RAM이 10GB여도 처리 가능 여부는 단순하지 않음 — OS 점유분, DataFrame 로드 시 메타 정보 포함분까지 고려하면 10GB를 넘길 수 있음.

1.3 polars 포지셔닝

  • 싱글 머신 극대화 — 단일 머신 자원을 최대한 활용
  • Apache Arrow 기반 — 열 기반 메모리 레이아웃 채용
  • 최적화 엔진 내장 — 쿼리 플랜 최적화 수행
  • 스트리밍 기능 — 데이터 전체를 메모리에 올리지 않고 처리 가능
  • 지연 연산 — 실행 전 최적화 후 일괄 수행
  • 확장 한계 — 수백 GB 이상은 분산 환경(spark) 필요

1.4 polars 정의

  • 개요 — 데이터 처리 극대화를 위해 설계된 차세대 데이터프레임 라이브러리
  • 기반 — 싱글 머신, Rust/Apache Arrow 개발
  • 강점 — 빠른 속도, 메모리 효율성, 병렬 처리
  • 공식 사이트https://pola.rs

2. 핵심 기술

2.1 Rust 기반 개발

  • 메모리 관리 혁신 — 소유권(ownership), 스코프 기반 관리 기법 적용. GC 오버헤드 없이 안정적
  • 저수준 제어 — C/C++에 필적하는 성능, 메모리 재사용성 높음
  • 안정성/동시성 — 컴파일 타임에 메모리 안전성 보장
  • 병렬 처리 최적화 — 자원 활용도 극대화, 한정 자원으로 최대 성능 도출

2.2 Apache Arrow 기반 구현

  • 열 기반 메모리 레이아웃 — 동일 컬럼 데이터가 메모리에 연속 배치
  • 벡터 연산 가속 — SIMD 활용한 빠른 처리
  • pandas 호환성 — pandas도 pyarrow 백엔드를 활용 중
  • CPU 캐시 특화 — 캐시 적중률 개선으로 메모리 스톨 증상 방지
  • Zero Copy 지원 — DataFrame 간 이동 시 복사 과정 제거, 직접 이동

2.3 효율화 기법

  • 지연(Lazy) 연산 — 연산을 설계하고 최적화 후 실행. 총 연산 시간이 pandas보다 빠름
  • 스트리밍 모드 — 데이터 전체를 메모리에 올리지 않고 필요한 부분만 처리
프레임워크  실행 방식  특징
TensorFlow Define(Python) And Run(C++) 그래프 정의 후 실행. 디버깅 불가, 텐서보드로 대체
PyTorch Define(Python) By Run(C++) 즉시 실행, 디버깅 가능. R&D에서 선호
polars (Lazy) 설계 → 최적화 → 실행 TensorFlow 스타일에 가까움, 그러나 최적화 이득 큼

지연 연산은 pandas의 즉시 실행 방식과 정반대 — 한 번에 설계하고 최적화 후 실행하기에 총 시간 면에서 우세함.

2.4 기대 효과

  • 대용량 데이터 대응 — 단일 PC에서 메모리 한계 극복
  • 비용 효율화 — 저사양 스펙으로도 대용량 처리 가능
  • 빠른 처리 속도 — 데이터 파이프라인 가속, 최적화 적용

3. 모듈 가져오기

import polars as pl

pl.__version__   # '1.35.2'
  • 관용적 alias — pl
  • 버전 체크 — pandas보다 메이저 버전이 빠르게 올라감

4. 자료구조

4.1 DataFrame 특징

  • pandas와 유사 — 2차원 배열 형태
  • 열 단위 타입 — 컬럼마다 다른 타입 보유 가능
  • 인덱스 없음 — pandas와 가장 큰 차이점

4.2 직접 생성

df = pl.DataFrame({
    "Key": list("AABBCCDD"),
    "cnt": [1, 4, 6, 2, 5, 5, 0, 3],
    "sum": [100, 400, 600, 200, 500, 500, 0, 300]
})
  • dict 입력 — pandas의 pd.DataFrame(dict)와 동일한 패턴
  • 컬럼명 = key, 데이터 = value

5. 파일 입출력

5.1 저장

df.write_csv('dummy.csv')              # 67 바이트
df.write_parquet('dummy.parquet')      # 1156 바이트
  • write_csv — 텍스트 기반, 사람이 읽을 수 있음
  • write_parquet — 압축 + 열 기반 저장. 작은 데이터에서는 메타 정보 때문에 오히려 크기가 큼

5.2 parquet 포맷 특징

  • 압축, 열 기반 저장 — 데이터가 커질수록 csv 대비 효율 상승
  • 메타 정보 포함 — 스키마(컬럼명/타입), 통계 데이터(min/max/Null 카운트), 딕셔너리 인코딩, 압축 알고리즘 헤더
  • 통계 데이터 사전 계산 — 컬럼별 최소/최대/Null 카운트를 미리 배치해 쿼리 가속
  • 딕셔너리 인코딩 — 중복 데이터를 숫자로 치환하는 매핑 테이블 활용
  • 바이너리 파일 — 정교하게 설계된 압축 구조

parquet 파일이 많아져 관리가 필요한 단계가 되면 테이블 포맷으로 묶어 관리 — Iceberg가 대표적이고, Spark + Iceberg 조합이 초대형 데이터 처리에 적합.

5.3 로드

%%time
df_pl_csv = pl.read_csv('dummy.csv')
df_pl_csv.estimated_size()

%%time
df_pl_parquet = pl.read_parquet('dummy.parquet')
df_pl_parquet.estimated_size()
  • read_csv / read_parquet — pandas와 거의 동일한 인터페이스
  • estimated_size() — 메모리 사용량 추정. pandas의 memory_usage().sum()에 대응
  • %%time — Jupyter/Colab의 셀 실행 시간 측정 매직

6. 외부 데이터 — NYC 택시 데이터로 성능 비교

6.1 데이터 출처

6.2 pandas 로드

%%time
import pandas as pd

src = '/content/drive/MyDrive/5. Data/taxi/yellow_tripdata_2026-01.parquet'
df_pd_taxi_yellow = pd.read_parquet(src)
df_pd_taxi_yellow.shape
  • read_parquet — pandas도 parquet 지원 (pyarrow 백엔드)
  • 메모리 사용량 확인 — df_pd_taxi_yellow.memory_usage(deep=True).sum()

6.3 polars 로드

%%time
import polars as pl

df_pl_taxi_yellow = pl.read_parquet(src)
df_pl_taxi_yellow.shape
  • estimated_size() — polars의 메모리 측정 메서드

동일 데이터 로드 시 속도·메모리 사용량 양측 모두에서 polars가 우세함. 대용량일수록 격차가 커지는 경향.

6.4 출력 차이

df_pd_taxi_yellow      # 왼쪽에 인덱스 컬럼 존재
df_pl_taxi_yellow      # 인덱스 없음, 컬럼명 아래에 타입 표기
  • pandas — 왼쪽에 자동 인덱스 표시
  • polars — 인덱스 자체가 없음. 컬럼명 아래에 타입이 함께 출력됨

7. 기본 정보 확인

7.1 메타 정보

df_pl_taxi_yellow.shape       # (행, 열)
df_pl_taxi_yellow.schema      # [(컬럼명, 타입), ...]
df_pl_taxi_yellow.columns     # 컬럼명 리스트
  • shape — pandas와 동일
  • schema — polars 전용. 컬럼명/순서/타입을 한 번에 확인
  • columns — 컬럼명만 추출

7.2 pandas와의 차이

기능  pandas  polars
인덱스 존재 없음
info() 있음 없음
describe() 있음 있음 (결측치도 함께 표기)
loc 있음 없음 (select() 등으로 대체)
iloc 있음 없음
schema 없음 있음

7.3 기초 통계

df_pl_taxi_yellow.describe()
  • 표시 항목 — 통계 지표 + 컬럼 타입 + 결측치 카운트
  • pandas와 차이 — pandas는 수치형만, polars는 결측치 정보까지 포함

polars는 인덱스 개념이 없기에 pandas의 loc/iloc처럼 인덱스 기반 인덱싱은 사용할 수 없음. 대신 select() 같은 명시적 메서드로 대체.


8. 열 데이터 추출

8.1 기본 인덱싱 (pandas 호환)

df_pl_taxi_yellow['payment_type']                           # 단일 컬럼
df_pl_taxi_yellow[['payment_type', 'fare_amount']]          # 다중 컬럼 (차원 유지)
  • 단일 컬럼 — pandas와 동일한 대괄호 인덱싱
  • 다중 컬럼 — 리스트로 감싸 추출, DataFrame 반환

8.2 select() — 명시적 추출

df_pl_taxi_yellow.select(['payment_type', 'fare_amount'])
  • 추출 행위 명시화 — pandas의 loc[]에 대응하는 polars 표준 방식
  • 명확한 의도 전달 — 단순 대괄호보다 가독성·일관성 우수

8.3 pl.col() — 컬럼 표현식

df_pl_taxi_yellow.select(pl.col('payment_type'))
df_pl_taxi_yellow.select(pl.col('payment_type'), pl.col('fare_amount'))
  • pl.col(컬럼명) — 컬럼을 명시적으로 표현하는 객체
  • 체이닝 가능 — 후속 연산(필터, 변환)을 자연스럽게 연결
  • 표현식 시스템 — polars의 핵심 개념. 단순 컬럼 이름이 아닌 "연산 명세"

8.4 전체 컬럼 선택

df_pl_taxi_yellow.select(pl.col('*'))
df_pl_taxi_yellow.select(pl.all())
  • pl.col('*') — 와일드카드로 모든 컬럼
  • pl.all() — 동일 의미의 단축 표현

8.5 특정 컬럼 제외

df_pl_taxi_yellow.select(pl.col('*').exclude('passenger_count'))
  • exclude() — pandas의 drop()에 대응
  • 표현식 메서드 체이닝 — *로 전체 선택 후 일부 제외

pandas는 짧게 줄여 쓰는 스타일이 흔한 반면, polars는 명시적·함수형 표기를 권장. 약식보다 함수로 명확하게 작성하는 컨벤션이 정착된 라이브러리.


요약

개념  핵심
포지셔닝 싱글 머신 극대화. pandas와 spark 사이의 영역
핵심 기술 Rust + Apache Arrow. 열 기반 메모리, Zero Copy
효율화 Lazy 연산, 스트리밍 모드, 병렬 처리
parquet 압축 + 열 기반 + 메타 정보 내장. 대용량에 유리
자료구조 DataFrame만. 인덱스 없음 (Series 개념 없음)
기본 정보 shape, schema, columns, describe. info()는 없음
메모리 측정 estimated_size() (pandas의 memory_usage 대응)
추출 — 기본 대괄호 인덱싱 pandas와 호환
추출 — 명시 select(), pl.col(), pl.all(), exclude()
스타일 약식 표현보다 함수 기반 명시적 표기 선호

polars는 pandas의 사용성을 계승하면서 Rust/Arrow 기반의 성능 최적화와 Lazy/Streaming 실행 모델을 더한 차세대 데이터프레임 라이브러리로, 단일 머신에서 처리 가능한 데이터 규모의 천장을 한 단계 끌어올리는 도구.