지연 평가 (Lazy Evaluation)

지연 평가 (Lazy Evaluation)

Lazy API로 작업하면 Polars는 쿼리를 줄 단위로 하나씩 실행하지 않고, 전체 쿼리를 처음부터 끝까지 하나로 묶어 처리해요. Polars를 제대로 활용하려면 Lazy API를 쓰는 것이 중요한데, 그 이유가 명확해요.

  • Lazy API는 쿼리 옵티마이저를 통해 자동 쿼리 최적화를 적용해줘요.
  • **스트리밍(streaming)**을 지원해서 메모리보다 큰 데이터도 다룰 수 있어요.
  • 데이터를 처리하기 전에 스키마 오류를 미리 잡아낼 수 있어요.

여기서는 파일에서 시작하든 이미 만들어진 DataFrame에서 시작하든, Lazy API를 어떻게 쓰는지 살펴볼게요.

파일에서 Lazy API 사용하기

이상적으로는 파일에서 바로 Lazy API를 쓰는 것이 좋아요. 쿼리 옵티마이저가 파일에서 읽어들이는 데이터 양 자체를 줄여줄 수 있거든요.

Reddit CSV 데이터로 lazy 쿼리를 만들어 몇 가지 변환을 적용해볼게요. pl.scan_csv로 쿼리를 시작하면 이미 Lazy API를 쓰고 있는 거예요.

q1 = (
    pl.scan_csv("docs/assets/data/reddit.csv")
    .with_columns(pl.col("name").str.to_uppercase())
    .filter(pl.col("comment_karma") > 0)
)

pl.scan_ 함수는 CSV, IPC, Parquet, JSON 등 여러 파일 형식에 대해서 제공돼요. 이 쿼리에서 Polars에 요청한 작업은 다음과 같아요.

  • Reddit CSV 파일에서 데이터를 불러오기
  • name 열을 대문자로 변환하기
  • comment_karma 열에 필터 적용하기

중요한 점은, 이 시점에서 lazy 쿼리는 실행되지 않는다는 거예요. lazy 쿼리를 실행하는 방법은 이 페이지에서 이어서 다룰게요.

DataFrame에서 Lazy API 사용하기

Lazy API에 접근하는 또 다른 방법은, 이미 메모리에 만들어진 DataFrame.lazy를 호출하는 거예요.

q3 = pl.DataFrame({"foo": ["a", "b", "c"], "bar": [0, 1, 2]}).lazy()

.lazy를 호출하면 DataFrameLazyFrame으로 변환돼요.