Polars là gì? DataFrame library Python nhanh hơn Pandas

Polars là gì? DataFrame library Python nhanh hơn Pandas

Polars DataFrame là thư viện xử lý dữ liệu tốc độ cao viết bằng Rust, thiết kế cho hiệu năng lớn nhất. Polars DataFrame vượt trội Pandas nhờ engine thực thi song song, quản lý bộ nhớ thông minh và API biểu thức (expression API) linh hoạt.

Trong thực tế, bạn gặp Polars trong các pipeline machine learning, phân tích log server, xử lý dataset chứng khoán hay báo cáo ETL trên data warehouse. Nếu Pandas mất hàng giờ để xử lý file lớn, Polars thường hoàn thành trong vài phút nhờ đa luồng và tối ưu tự động.

Tại sao Polars nhanh hơn Pandas?

Pandas chạy đơn luồng (single-threaded), giới hạn hiệu năng trên CPU đa nhân hiện nay. Polars giải quyết bài toán này bằng ba trụ cột:

  • Đa luồng tự động: Polars tận dụng tất cả nhân CPU mà không cần cấu hình thêm.
  • Zero-copy & Apache Arrow: Dữ liệu lưu ở định dạng cột (columnar), chia sẻ bộ nhớ giữa Rust và Python.
  • Query optimizer: Engine tối ưu kế hoạch thực thi trước khi chạy — lọc sớm, gộp phép toán, loại cột không dùng.
Biểu đồ so sánh hiệu năng Polars vs Pandas xử lý dataset 1GB
So sánh hiệu năng Polars vs Pandas

Kiến trúc cốt lõi

DataFrame và Series

DataFrame là bảng dữ liệu 2 chiều; Series là cột đơn lẻ. Cả hai đều bất biến (immutable) — phép biến đổi trả về đối tượng mới, an toàn cho xử lý song song.

Expression API

Thay vì gán biến trung gian, bạn viết chuỗi biểu thức:

df.filter(pl.col("age") > 30)
    .group_by("city")
    .agg(pl.col("salary").mean())

Engine thấy toàn bộ pipeline, tối ưu hoá trước khi thực thi. Expression có thể tổ hợp lồng nhau (nested expressions) — ví dụ pl.col("x").filter(pl.col("y") > 0).mean() — giúp logic phức tạp gọn trong một dòng. So với Pandas df[df['y']>0]['x'].mean(), Polars không tạo bản sao trung gian.

LazyFrame — chế độ lười biếng

LazyFrame trì hoãn chạy cho đến khi gọi .collect(). Lợi ích:

  • Tối ưu toàn cục (predicate pushdown, projection pushdown)
  • Xử lý dữ liệu lớn hơn RAM (streaming)
  • Kết hợp nhiều nguồn dữ liệu trước khi materialize

Predicate pushdown đẩy điều kiện lọc xuống nguồn dữ liệu (CSV, Parquet) — chỉ đọc row cần thiết. Projection pushdown chỉ nạp cột dùng đến. Streaming mode (.collect(streaming=True)) xử lý theo chunk, cho phép dataset lớn hơn bộ nhớ vật lý.

So sánh nhanh Polars vs Pandas

Tiêu chí Pandas Polars
Ngôn ngữ cốt lõi Python + C Rust
Đa luồng Không (cần modin/dask) Tự động
Bộ nhớ Row-major, copy nhiều Columnar (Arrow), zero-copy
API DataFrame method chaining Expression API + SQL context
Streaming / out-of-core Yếu Mạnh (LazyFrame)
Học tập Dễ, tài liệu nhiều Khá dễ, cú pháp quen thuộc

Cài đặt và bắt đầu

pip install polars
# hoặc với backend pyarrow
pip install "polars[pyarrow]"

Ví dụ đọc CSV 100 triệu dòng:

import polars as pl

# Eager mode
df = pl.read_csv("large_file.csv")
print(df.filter(pl.col("value") > 100).select("id", "name"))

# Lazy mode — khuyến nghị cho big data
lf = pl.scan_csv("large_file.csv")
result = lf.filter(pl.col("value") > 100).select("id", "name").collect()
Kiến trúc Polars: DataFrame, Series, Expression API và LazyFrame
Kiến trúc Polars: Eager vs Lazy execution

Thao tác thường gặp

Lọc và chọn cột

df.filter((pl.col("age") > 25) & (pl.col("city") == "Hanoi"))
  .select(["name", "salary", "department"])

Group by và aggregation

df.group_by("department").agg([
    pl.col("salary").mean().alias("avg_salary"),
    pl.col("salary").max().alias("max_salary"),
    pl.count().alias("headcount")
])

Join đa luồng

# Hash join tự động song song
result = df_left.join(df_right, on="user_id", how="inner")

Window functions

df.with_columns([
    pl.col("salary").rank().over("department").alias("rank_in_dept"),
    pl.col("salary").mean().over("department").alias("dept_avg")
])

Tích hợp hệ sinh thái

  • Apache Arrow / Parquet: pl.read_parquet(), df.write_parquet() — định dạng cột chuẩn, nén tốt.
  • Pandas / NumPy: df.to_pandas(), pl.from_pandas(pdf) — chuyển đổi zero-copy khi có pyarrow.
  • SQL: pl.sql("SELECT * FROM df WHERE ...") — chạy SQL trực tiếp trên DataFrame.
  • DuckDB: pl.read_database() — truy vấn DuckDB, trả về Polars DataFrame.
  • PyTorch / TensorFlow: df.to_numpy(), df.to_torch() — pipeline ML liền mạch.

Tham khảo tài liệu chính thức: https://docs.pola.rs/

Mẹo hiệu năng và best practices

  • Dùng LazyFrame mặc định: pl.scan_csv() thay vì pl.read_csv() cho file lớn — tận dụng predicate/projection pushdown.
  • Chọn kiểu dữ liệu phù hợp: pl.Int32, pl.Float32 thay vì 64-bit khi giá trị cho phép — tiết kiệm 50% RAM.
  • Tránh to_pandas() không cần thiết: Giữ Polars end-to-end; chỉ chuyển khi thư viện ML yêu cầu.
  • Partition Parquet: Ghi theo partition_by=["year", "month"] — query sau chỉ đọc partition cần thiết.
  • Cấu hình thread pool: pl.Config.set_tbl_rows(20) cho hiển thị, POLARS_MAX_THREADS env var giới hạn nhân CPU (mặc định: tất cả).

Khi nào nên dùng Polars?

  • Xử lý dữ liệu > 1GB trên máy đơn (laptop/server)
  • Cần tốc độ đọc/ghi Parquet, CSV lớn
  • Pipeline ETL/ELT sản xuất, yêu cầu ổn định và tái lập
  • Kết hợp SQL + DataFrame trong cùng codebase
  • Đội ngũ đã biết Pandas — chuyển đổi nhẹ nhàng

Hạn chế cần biết

  • Cộng đồng nhỏ hơn Pandas, ít tutorial tiếng Việt
  • Một số phép toán nâng cao (time-series resample phức tạp) chưa bằng Pandas
  • Debug expression pipeline khó hơn method chaining quen thuộc
  • Phiên bản < 1.0 — API có thể thay đổi (dù đã ổn định từ 0.19+)
Screenshot IDE hiển thị autocomplete Polars expression API
Autocomplete Polars expression API trong IDE

Kết luận

Polars DataFrame mang hiệu năng Rust vào Python mà không đánh đổi trải nghiệm lập trình. Với Expression API, LazyFrame và đa luồng tự động, Polars là lựa chọn hợp lý cho xử lý dữ liệu lớn, pipeline production và thay thế Pandas khi hiệu năng trở thành bottleneck. Hãy thử pip install polars và chạy trên dataset thực tế — chênh lệch tốc độ thường từ 3x đến 50x.

Cập nhật 2024: Polars 1.0 đã phát hành, API ổn định, sẵn sàng production.


Tags: Framework, Git, Class

Category: Lập trình (ID: 107)

Tôi là một lập trình viên IOS. Code chính là IOS nhưng thỉnnh thoảng vẫn đá sang Android hoặc web. Mặc dù không quá thông thạo nhưng tôi sẽ chia sẻ những kiến thức mà mình đã tìm hiểu, áp dụng qua.

Bài viết liên quan

Connection pooling là gì? HikariCP, PgBouncer, ProxySQL so sánh

Vì sao cần connection pool? Trong ứng dụng web hiện đại, mỗi request HTTP thường cần ít nhất một kết nối database để đọc/ghi dữ liệu. Nếu mỗi request tự…

Xem thêm

WebTransport là gì? Giao thức UDP thay thế WebSocket cho realtime

WebTransport là giao thức mạng mới của W3C cho phép client kết nối trực tiếp đến server qua UDP, vượt qua giới hạn latency và head-of-line blocking của WebSocket. Với…

Xem thêm

Convex là gì? Backend fullstack realtime cho Next.js React

Convex là gì? Backend fullstack realtime cho Next.js React Convex là một nền tảng backend-as-a-service (BaaS) mới, được thiết kế đặc biệt cho các ứng dụng fullstack hiện đại sử…

Xem thêm
0 0 đánh giá
Article Rating
Theo dõi
Thông báo của
guest
0 Comments
Cũ nhất
Mới nhất Được bỏ phiếu nhiều nhất