
Polars DataFrame là gì?
Polars DataFrame là thư viện xử lý dữ liệu hiệu năng cao viết bằng Rust, được thiết kế như một sự thay thế nhanh hơn và tiết kiệm bộ nhớ hơn so với pandas. Khác với pandas hoạt động đơn luồng và nạp toàn bộ dữ liệu vào RAM, Polars sử dụng đa luồng tự động, lazy evaluation (đánh giá lười) và query optimization để xử lý tập dữ liệu lớn (GB–TB) trên phần cứng thông thường.

Tại sao Polars nhanh hơn Pandas?
Ba yếu tố cốt lõi tạo nên lợi thế hiệu năng của Polars:
- Đa luồng mặc định: Polars tự động phân phối tác vụ lên tất cả nhân CPU có sẵn. Pandas chỉ chạy đơn luồng trừ khi dùng thư viện bên ngoài (modin, dask).
- Lazy evaluation & query optimizer: Với API
LazyFrame, Polars xây dựng execution plan, tối ưu hóa (predicate pushdown, projection pushdown, join reorder) trước khi thực thi — giảm I/O và tính toán dư thừa. - Apache Arrow memory format: Dữ liệu lưu ở định dạng cột (columnar) không copy, zero-copy cho phép chia sẻ bộ nhớ giữa Python, Rust, và engine query khác nhau.
Hai API: Eager vs Lazy
Polars cung cấp hai giao diện song song:
| Đặc điểm | Eager API (pl.DataFrame) |
Lazy API (pl.LazyFrame) |
|---|---|---|
| Thực thi | Ngay lập tức (eager) | Chỉ khi gọi .collect() |
| Tối ưu hóa | Không có | Query optimizer đầy đủ |
| Phù hợp | Dữ liệu nhỏ, khám phá, debug | Dữ liệu lớn, pipeline production |
| Memory | Nạp toàn bộ | Streaming, out-of-core |
Ví dụ Lazy API — lọc 1 tỷ dòng, chỉ đọc các cột cần thiết:
import polars as pl
lf = pl.scan_parquet("s3://bucket/large_dataset/*.parquet")
result = (
lf.filter(pl.col("amount") > 1000)
.select(["user_id", "amount", "timestamp"])
.group_by("user_id")
.agg(pl.col("amount").sum().alias("total_spent"))
.sort("total_spent", descending=True)
.limit(100)
.collect()
)

So sánh nhanh: Polars vs Pandas vs DuckDB
| Tiêu chí | Polars | Pandas | DuckDB |
|---|---|---|---|
| Ngôn ngữ core | Rust | C/Python | C++ |
| Đa luồng | Tự động | Cần modin/dask | Tự động |
| Out-of-core | Có (streaming) | Khó | Có |
| SQL interface | Có (experimental) | Không | Nội tại |
| Arrow/Parquet | Native | Ququa pyarrow | Native |
| Ecosystem ML | Đang phát triển | Rất lớn | Trung bình |
Khi nào nên chọn Polars?
- Xử lý file Parquet/CSV lớn (> RAM) mà không muốn cài Spark/Dask
- Pipeline ETL production cần độ tin cậy, reproducible, CI/CD friendly
- Team dùng Rust/Python song song — Polars có bindings song song cho cả hai
- Cần query optimizer tự động cho join, filter, aggregation phức tạp
Các lệnh thường dùng
# Cài đặt
pip install polars # Python
cargo add polars # Rust
# Đọc ghi Parquet (hiệu năng tốt nhất)
df = pl.read_parquet("data.parquet")
df.write_parquet("output.parquet")
# Streaming cho file lớn hơn RAM
pl.scan_parquet("huge.parquet").filter(...).sink_parquet("out.parquet")
# Expression API - mạnh mẽ, declarative
df.with_columns([
(pl.col("price") * pl.col("qty")).alias("revenue"),
pl.col("date").dt.year().alias("year")
]).group_by("year").agg(pl.col("revenue").sum())
Hạn chế cần biết
- Ecosystem ML chưa bằng pandas: Một số thư viện (statsmodels, scikit-learn) vẫn mong đợi
pd.DataFrame— cần.to_pandas()chuyển đổi. - Multi-index không hỗ trợ: Polars dùng hierarchical grouping thay vì MultiIndex.
- API thay đổi nhanh: Polars 1.x ổn định nhưng các phiên bản 0.x có breaking changes thường xuyên.
Kết luận
Polars DataFrame mang lại hiệu năng cấp Spark với API Python quen thuộc và không phụ thuộc cluster. Với lazy evaluation, đa luồng tự động, và định dạng Arrow native, Polars là lựa chọn hàng đầu cho data engineering hiện đại trên single-node. Nếu bạn đang gặp giới hạn RAM/CPU với pandas — hãy thử pl.scan_parquet() ngay hôm nay.
Nguồn tham khảo: Polars Official Documentation, Polars GitHub Repository, DuckDB Polars Integration Guide
