Polars - DataFrame Siêu Nhanh
1. Tại sao Polars?
Polars là thư viện DataFrame mới, được viết bằng Rust, nhanh hơn Pandas 10-100x!
| Tiêu chí | Pandas | Polars |
|---|---|---|
| Ngôn ngữ | Python/C | Rust |
| Tốc độ | Chuẩn | 10-100x nhanh hơn |
| Memory | Cao | Thấp hơn nhiều |
| Parallel | Không | Tự động multi-core |
| Lazy eval | Không | Có |
| API | Dễ dùng | Dễ dùng |
Python
1import polars as pl2print(pl.__version__) # 0.x.x2. Tạo DataFrame
2.1 Từ Dictionary
Python
1import polars as pl23# Từ dict4df = pl.DataFrame({5 "name": ["Alice", "Bob", "Charlie"],6 "age": [25, 30, 35],7 "salary": [50000, 60000, 70000]8})910print(df)11# shape: (3, 3)12# ┌─────────┬─────┬────────┐13# │ name ┆ age ┆ salary │14# │ --- ┆ --- ┆ --- │15# │ str ┆ i64 ┆ i64 │16# ╞═════════╪═════╪════════╡17# │ Alice ┆ 25 ┆ 50000 │18# │ Bob ┆ 30 ┆ 60000 │19# │ Charlie ┆ 35 ┆ 70000 │20# └─────────┴─────┴────────┘2.2 Đọc File
Python
1# CSV2df = pl.read_csv("data.csv")34# Parquet (tối ưu nhất cho Polars)5df = pl.read_parquet("data.parquet")67# JSON8df = pl.read_json("data.json")910# Excel11df = pl.read_excel("data.xlsx")1213# Lazy loading - Không load hết vào RAM14df_lazy = pl.scan_csv("large_file.csv")15df_lazy = pl.scan_parquet("large_file.parquet")3. Selection với Expressions
3.1 Select Columns
Python
1# Select columns2df.select("name", "age")3df.select(pl.col("name"), pl.col("age"))45# Select tất cả6df.select(pl.all())78# Select với pattern9df.select(pl.col("^salary.*$")) # Regex10df.select(pl.col("*_id")) # Wildcard3.2 Filter Rows
Python
1# Filter với expressions2df.filter(pl.col("age") > 30)34# Multiple conditions5df.filter(6 (pl.col("age") > 25) & (pl.col("salary") > 55000)7)89# isin10df.filter(pl.col("name").is_in(["Alice", "Bob"]))1112# String contains13df.filter(pl.col("name").str.contains("A"))3.3 Expressions - Core của Polars
Python
1# Expressions rất powerful!2df.select(3 pl.col("name"),4 pl.col("age"),5 pl.col("salary"),6 7 # Tính toán8 (pl.col("salary") / 12).alias("monthly_salary"),9 10 # Conditions11 pl.when(pl.col("age") > 30)12 .then(pl.lit("Senior"))13 .otherwise(pl.lit("Junior"))14 .alias("level"),15 16 # String operations17 pl.col("name").str.to_uppercase().alias("NAME_UPPER"),18 19 # Aggregations (broadcast)20 pl.col("salary").mean().alias("avg_salary"),21)4. Transformations
4.1 With Columns - Thêm/Sửa cột
Python
1df = df.with_columns(2 # Cột mới từ tính toán3 (pl.col("salary") * 1.1).alias("new_salary"),4 5 # Age group6 pl.when(pl.col("age") < 30)7 .then(pl.lit("Young"))8 .when(pl.col("age") < 40)9 .then(pl.lit("Middle"))10 .otherwise(pl.lit("Senior"))11 .alias("age_group"),12 13 # String processing14 pl.col("name").str.len_chars().alias("name_length"),15)4.2 Sort
Python
1# Sort ascending2df.sort("age")34# Sort descending5df.sort("age", descending=True)67# Sort by multiple columns8df.sort(["city", "age"], descending=[False, True])4.3 Rename và Drop
Python
1# Rename2df.rename({"old_name": "new_name"})34# Drop columns5df.drop("column_to_drop")6df.drop(["col1", "col2"])5. Group By và Aggregations
5.1 Basic Group By
Python
1df.group_by("city").agg(2 pl.col("salary").sum().alias("total_salary"),3 pl.col("salary").mean().alias("avg_salary"),4 pl.col("age").max().alias("max_age"),5 pl.len().alias("count")6)5.2 Nhiều Aggregations
Python
1df.group_by("city", "department").agg(2 # Sum3 pl.col("salary").sum().alias("total_salary"),4 5 # Mean6 pl.col("age").mean().alias("avg_age"),7 8 # Count unique9 pl.col("employee_id").n_unique().alias("unique_employees"),10 11 # First/Last12 pl.col("hire_date").first().alias("first_hire"),13 pl.col("hire_date").last().alias("last_hire"),14 15 # List aggregation16 pl.col("name").alias("employees"), # List of names17 18 # Quantiles19 pl.col("salary").quantile(0.5).alias("median_salary"),20)5.3 Window Functions
Python
1df.with_columns(2 # Running sum3 pl.col("sales").cum_sum().over("city").alias("cumulative_sales"),4 5 # Rank6 pl.col("salary").rank().over("department").alias("salary_rank"),7 8 # Percent of group9 (pl.col("sales") / pl.col("sales").sum().over("city") * 100)10 .alias("pct_of_city"),11 12 # Lead/Lag13 pl.col("date").shift(1).over("customer_id").alias("prev_date"),14 pl.col("date").shift(-1).over("customer_id").alias("next_date"),15)6. Lazy Evaluation
Lazy mode là sức mạnh của Polars - tối ưu query trước khi thực thi!
6.1 Lazy Frame
Python
1# Tạo LazyFrame2df_lazy = pl.scan_csv("large_file.csv")34# Hoặc từ DataFrame5df_lazy = df.lazy()67# Chain operations (chưa thực thi!)8result_lazy = (9 df_lazy10 .filter(pl.col("age") > 25)11 .group_by("city")12 .agg(pl.col("salary").mean())13 .sort("salary", descending=True)14)1516# Thực thi và collect kết quả17result = result_lazy.collect()1819# Xem query plan20print(result_lazy.explain())6.2 Streaming cho Big Data
Python
1# Streaming mode - xử lý file lớn hơn RAM2result = (3 pl.scan_csv("huge_file.csv")4 .filter(pl.col("value") > 100)5 .group_by("category")6 .agg(pl.col("value").sum())7 .collect(streaming=True) # Streaming execution8)7. Joins
Python
1# Sample DataFrames2orders = pl.DataFrame({3 "order_id": [1, 2, 3],4 "customer_id": [101, 102, 101],5 "amount": [100, 200, 150]6})78customers = pl.DataFrame({9 "customer_id": [101, 102, 103],10 "name": ["Alice", "Bob", "Charlie"]11})1213# Inner join14orders.join(customers, on="customer_id", how="inner")1516# Left join17orders.join(customers, on="customer_id", how="left")1819# Full outer join20orders.join(customers, on="customer_id", how="outer")2122# Join on different columns23orders.join(24 customers, 25 left_on="cust_id", 26 right_on="customer_id"27)8. String Operations
Python
1df.with_columns(2 # Upper/Lower3 pl.col("name").str.to_uppercase().alias("upper"),4 pl.col("name").str.to_lowercase().alias("lower"),5 6 # Contains7 pl.col("name").str.contains("A").alias("has_A"),8 9 # Replace10 pl.col("text").str.replace("old", "new"),11 pl.col("text").str.replace_all(r"\d+", "X"), # Regex12 13 # Split14 pl.col("full_name").str.split(" ").alias("name_parts"),15 16 # Extract17 pl.col("email").str.extract(r"@(\w+)\.").alias("domain"),18 19 # Length20 pl.col("name").str.len_chars().alias("char_count"),21)9. Date/Time Operations
Python
1df = pl.DataFrame({2 "date": ["2024-01-15", "2024-02-20", "2024-03-25"],3}).with_columns(4 pl.col("date").str.to_datetime().alias("datetime")5)67df.with_columns(8 # Extract components9 pl.col("datetime").dt.year().alias("year"),10 pl.col("datetime").dt.month().alias("month"),11 pl.col("datetime").dt.day().alias("day"),12 pl.col("datetime").dt.weekday().alias("weekday"),13 14 # Date arithmetic15 (pl.col("datetime") + pl.duration(days=7)).alias("plus_week"),16 17 # Date diff18 (pl.col("datetime") - pl.col("datetime").shift(1))19 .dt.total_days()20 .alias("days_between"),21)10. Pandas ↔ Polars Conversion
Python
1import pandas as pd2import polars as pl34# Pandas → Polars5pandas_df = pd.DataFrame({"a": [1, 2, 3]})6polars_df = pl.from_pandas(pandas_df)78# Polars → Pandas9polars_df = pl.DataFrame({"a": [1, 2, 3]})10pandas_df = polars_df.to_pandas()11. So sánh Pandas vs Polars
Python
1# PANDAS2import pandas as pd34df_pd = pd.read_csv("data.csv")5result_pd = (6 df_pd[df_pd['age'] > 25]7 .groupby('city')['salary']8 .mean()9 .reset_index()10 .sort_values('salary', ascending=False)11)1213# POLARS (dễ đọc hơn, nhanh hơn!)14import polars as pl1516result_pl = (17 pl.scan_csv("data.csv") # Lazy18 .filter(pl.col("age") > 25)19 .group_by("city")20 .agg(pl.col("salary").mean())21 .sort("salary", descending=True)22 .collect() # Execute23)Tổng Kết
Trong bài này, bạn đã học:
- ✅ Polars là gì và tại sao nhanh hơn Pandas
- ✅ Expressions - core concept của Polars
- ✅ Selection, Filter, Transform
- ✅ Group By và Window Functions
- ✅ Lazy Evaluation và Streaming
- ✅ String và DateTime operations
Bài tiếp theo: Data Cleaning & Preprocessing - Làm sạch dữ liệu!
