关于 polars-dataframes
polars-dataframes 是面向 Python 表格数据处理的技能,围绕 Polars DataFrame 库展开,涵盖表达式操作、惰性查询优化、并行处理和数据读写。
主要功能
- 01基于表达式的 DataFrame 操作
- 02惰性查询优化与流式处理
- 03连接、分组与重塑数据
- 04CSV、Parquet、JSON 和数据库读写
适用场景
- 01构建表格数据 ETL 工作流
- 02连接并汇总大型数据表
- 03创建时间序列特征
- 04以性能为由迁移 pandas 工作流
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jaechang-hits/ sciagent-skills --skill polars-dataframes安装后在 Claude Code 中输入/polars-dataframes确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/advanced_operations.mdio_best_practices.mdpandas_migration.md详细介绍
Polars DataFrames
概述
Polars 是一款高性能的 Python DataFrame 库,基于 Apache Arrow 构建,并采用 Rust 后端。它提供基于表达式的 API,支持惰性求值和自动并行化,可高效地处理、转换和分析数据。
适用场景
- 处理大小在 100 MB 到 100 GB、可放入 RAM 的表格数据集
- 需要快速读取、转换和写入数据的 ETL 工作流
- 在性能至关重要时替代 pandas(通常可提升 10–100 倍速度)
- 具有自动优化功能(谓词下推/投影下推)的惰性查询工作流
- 连接、透视和重塑大型表格
- 高效读取 Parquet、CSV、JSON 或云存储中的数据
- 窗口函数和复杂的分组聚合
- 对于大于 RAM 的数据,请改用 Dask 或 Vaex
- 对于 GPU 加速的 DataFrame,请改用 cuDF
前置条件
pip install polars
# Optional extras:
pip install polars[all] # All I/O backends
pip install polars[pandas] # Pandas interop
pip install polars[numpy] # NumPy interop
pip install connectorx sqlalchemy # Database connectivity
快速入门
import polars as pl
# Create DataFrame
df = pl.DataFrame({
"name": ["Alice", "Bob", "Charlie", "Diana"],
"dept": ["Sales", "Eng", "Sales", "Eng"],
"salary": [70000, 85000, 72000, 90000],
})
# Expression-based pipeline
result = (
df.filter(pl.col("salary") > 71000)
.with_columns(bonus=pl.col("salary") * 0.1)
.group_by("dept")
.agg(
pl.col("salary").mean().alias("avg_salary"),
pl.len().alias("count"),
)
)
print(result)
# shape: (2, 3)
# ┌───────┬────────────┬───────┐
# │ dept ┆ avg_salary ┆ count │
# ├───────┼────────────┼───────┤
# │ Eng ┆ 87500.0 ┆ 2 │
# │ Sales ┆ 72000.0 ┆ 1 │
# └───────┴────────────┴───────┘
核心 API
1. DataFrame 操作
选择、筛选、添加/修改列、排序和抽样行。
import polars as pl
df = pl.DataFrame({
"id": [1, 2, 3, 4, 5],
"name": ["Alice", "Bob", "Charlie", "Diana", "Eve"],
"age": [25, 30, 35, 28, 32],
"score": [88.5, 92.0, 76.3, 95.1, 84.7],
})
# Select columns (with computed expressions)
selected = df.select(
"name",
pl.col("age"),
(pl.col("score") / 100).alias("score_pct"),
)
print(selected.shape) # (5, 3)
# Filter rows (multiple conditions → implicit AND)
filtered = df.filter(
pl.col("age") > 27,
pl.col("score") > 80,
)
print(filtered.shape) # (3, 4) — Bob, Diana, Eve
# Add columns (preserves existing)
enriched = df.with_columns(
grade=pl.when(pl.col("score") >= 90).then(pl.lit("A"))
.when(pl.col("score") >= 80).then(pl.lit("B"))
.otherwise(pl.lit("C")),
age_months=pl.col("age") * 12,
)
print(enriched.columns)
# ['id', 'name', 'age', 'score', 'grade', 'age_months']
# Sort
df.sort("score", descending=True).head(3)
2. GroupBy 和聚合
对行分组并计算汇总统计数据。
import polars as pl
sales = pl.DataFrame({
"region": ["East", "West", "East", "West", "East", "West"],
"product": ["A", "A", "B", "B", "A", "B"],
"revenue": [100, 150, 200, 180, 120, 210],
"units": [10, 15, 20, 18, 12, 21],
})
# Basic group_by
summary = sales.group_by("region").agg(
pl.col("revenue").sum().alias("total_rev"),
pl.col("revenue").mean().alias("avg_rev"),
pl.len().alias("n_transactions"),
)
print(summary)
# Multiple keys + conditional aggregation
by_rp = sales.group_by("region", "product").agg(
pl.col("revenue").sum(),
(pl.col("units") > 15).sum().alias("large_orders"),
)
print(by_rp)
# Window functions with over() — add group stats without collapsing rows
enriched = sales.with_columns(
region_avg=pl.col("revenue").mean().over("region"),
rank_in_region=pl.col("revenue").rank(descending=True).over("region"),
pct_of_region=pl.col("revenue") / pl.col("revenue").sum().over("region"),
)
print(enriched.select("region", "product", "revenue", "region_avg", "rank_in_region"))
3. 连接
根据共享键合并 DataFrame。
import polars as pl
customers = pl.DataFrame({
"cid": [1, 2, 3, 4],
"name": ["Alice", "Bob", "Charlie", "Diana"],
})
orders = pl.DataFrame({
"oid": [101, 102, 103, 104],
"cid": [1, 2, 1, 5],
"amount": [100, 200, 150, 300],
})
# Inner join — only matching rows
inner = customers.join(orders, on="cid", how="inner")
print(inner.shape) # (3, 4) — cid 1 (×2), cid 2
# Left join — all left rows, nulls where no match
left = customers.join(orders, on="cid", how="left")
print(left.shape) # (4, 4) — Charlie and Diana have null amount
# Anti join — left rows WITHOUT a match in right
no_orders = customers.join(orders, on="cid", how="anti")
print(no_orders["name"].to_list()) # ['Charlie', 'Diana']
# Join on different column names
customers.join(orders, left_on="cid", right_on="cid", suffix="_order")
# Asof join — match to nearest timestamp (time-series alignment)
quotes = pl.DataFrame({
"time": [1.0, 2.0, 3.0, 4.0],
"price": [100, 101, 102, 103],
}).cast({"time": pl.Float64})
trades = pl.DataFrame({
"time": [1.5, 3.2],
"qty": [50, 75],
}).cast({"time": pl.Float64})
result = trades.join_asof(quotes, on="time", strategy="backward")
print(result)
# time=1.5 matched price=100, time=3.2 matched price=102
4. 重塑
透视、逆透视、展开和转置操作。
import polars as pl
# --- Pivot (long → wide) ---
long = pl.DataFrame({
"date": ["Jan", "Jan", "Feb", "Feb"],
"product": ["A", "B", "A", "B"],
"sales": [100, 150, 120, 160],
})
wide = long.pivot(values="sales", index="date", columns="product")
print(wide)
# date | A | B
# Jan | 100 | 150
# Feb | 120 | 160
# --- Unpivot (wide → long) ---
back_to_long = wide.unpivot(
index="date", on=["A", "B"],
variable_name="product", value_name="sales",
)
print(back_to_long.shape) # (4, 3)
# --- Explode list columns ---
nested = pl.DataFrame({
"id": [1, 2],
"tags": [["a", "b", "c"], ["d", "e"]],
})
flat = nested.explode("tags")
print(flat.shape) # (5, 2)
5. 数据 I/O
读取和写入 CSV、Parquet、JSON、Excel、数据库和云存储中的数据。
import polars as pl
# --- CSV ---
df = pl.read_csv("data.csv")
df.write_csv("output.csv")
# --- Parquet (recommended for performance) ---
df = pl.read_parquet("data.parquet")
df.write_parquet("output.parquet", compression="zstd")
# --- JSON / NDJSON ---
df = pl.read_ndjson("data.ndjson")
df.write_ndjson("output.ndjson")
# --- Excel ---
df = pl.read_excel("data.xlsx", sheet_name="Sheet1")
df.write_excel("output.xlsx")
# --- Lazy scan (preferred for large files) ---
lf = pl.scan_csv("large.csv")
result = lf.filter(pl.col("value") > 0).select("id", "value").collect()
print(result.shape)
# --- Database ---
df = pl.read_database_uri(
"SELECT * FROM users WHERE age > 25",
uri="postgresql://user:pass@localhost/db",
)
# --- Cloud storage (S3, GCS, Azure) ---
df = pl.read_parquet("s3://bucket/data.parquet")
df = pl.scan_parquet("gs://bucket/data/*.parquet").collect()
# --- Partitioned Parquet (Hive-style) ---
df.write_parquet("output_dir", partition_by=["year", "month"])
lf = pl.scan_parquet("output_dir/**/*.parquet")
6. 表达式 API
字符串、日期时间、列表和条件操作。
import polars as pl
from datetime import date
df = pl.DataFrame({
"text": ["Hello World", "foo bar", "POLARS"],
"dt": [date(2023, 1, 15), date(2023, 6, 30), date(2024, 12, 1)],
"values": [[1, 2, 3], [4, 5], [6]],
})
# String operations
strings = df.select(
lower=pl.col("text").str.to_lowercase(),
length=pl.col("text").str.len_chars(),
contains_o=pl.col("text").str.contains("o"),
split=pl.col("text").str.split(" "),
)
print(strings)
# Datetime operations
dates = df.select(
year=pl.col("dt").dt.year(),
month=pl.col("dt").dt.month(),
weekday=pl.col("dt").dt.weekday(),
quarter=pl.col("dt").dt.quarter(),
)
print(dates)
# List operations
lists = df.select(
list_len=pl.col("values").list.len(),
list_sum=pl.col("values").list.sum(),
first=pl.col("values").list.first(),
)
print(lists)
# Conditional expressions (when/then/otherwise)
df = pl.DataFrame({"score": [45, 72, 88, 95, 60]})
result = df.with_columns(
grade=pl.when(pl.col("score") >= 90).then(pl.lit("A"))
.when(pl.col("score") >= 80).then(pl.lit("B"))
.when(pl.col("score") >= 70).then(pl.lit("C"))
.otherwise(pl.lit("F")),
)
print(result)
# Null handling
df2 = pl.DataFrame({"x": [1, None, 3, None, 5]})
filled = df2.with_columns(
filled=pl.col("x").fill_null(0),
forward=pl.col("x").fill_null(strategy="forward"),
is_null=pl.col("x").is_null(),
)
print(filled)
# Multi-column operations with regex selector
df3 = pl.DataFrame({"val_a": [1, 2], "val_b": [3, 4], "name": ["x", "y"]})
doubled = df3.select(pl.col("^val_.*$") * 2)
print(doubled)
7. 惰性求值
在执行前构建优化后的查询计划。
import polars as pl
# Lazy mode: build plan, optimize, then execute
lf = pl.scan_csv("large_dataset.csv")
result = (
lf
.select("user_id", "category", "amount", "date") # projection pushdown
.filter(pl.col("amount") > 100) # predicate pushdown
.with_columns(pl.col("date").str.to_date())
.group_by("category")
.agg(
pl.col("amount").sum().alias("total"),
pl.col("user_id").n_unique().alias("unique_users"),
)
.sort("total", descending=True)
)
# Inspect the optimized plan
print(result.explain())
# Execute
df = result.collect()
print(df)
# Streaming mode for very large data
lf = pl.scan_parquet("data/*.parquet")
result = (
lf
.filter(pl.col("year") >= 2023)
.group_by("region")
.agg(pl.col("sales").sum())
.collect(streaming=True) # processes in batches
)
print(result)
# Sink directly to file (no full materialization)
lf.filter(pl.col("active")).sink_parquet("filtered_output.parquet")
核心概念
惰性与即时求值对比
| 方面 | 即时求值(DataFrame) | 惰性求值(LazyFrame) |
|---|---|---|
| 创建方式 | pl.read_*()、pl.DataFrame() | pl.scan_*()、df.lazy() |
| 执行时机 | 立即 | 调用 .collect() 时 |
| 优化 | 无 | 谓词/投影下推、连接重排序 |
| 流式处理 | 否 | collect(streaming=True) |
| 适用场景 | 小型数据、交互式操作 | 大型数据、工作流 |
Polars 数据类型
| 类型 | Python 对应类型 | 说明 |
|---|---|---|
Int8/16/32/64 | int | 选择满足需求的最小类型 |
UInt8/16/32/64 | int | 无符号 |
Float32/64 | float | 默认使用 Float64 |
Boolean | bool | |
Utf8 | str | 字符串类型 |
Categorical | — | 低基数字符串(GroupBy 更快) |
Date | datetime.date | 不含时间的日期 |
Datetime | datetime.datetime | 微秒精度 |
Duration | datetime.timedelta | 时间差 |
List | list | 可变长度列表 |
Struct | dict | 命名字段 |
Null | None | 全为空值的列 |
与 Pandas 的主要区别
- 没有索引:只能按位置访问行;没有带标签的
.loc/.iloc - 类型严格:不会静默强制转换类型;必须显式调用
.cast() - 使用表达式,而非方法:使用
pl.col("x").mean(),而不是df["x"].mean() - 默认并行:所有列操作都会并行运行
- 惰性求值:可通过
LazyFrame实现查询优化
常见工作流
1. ETL 工作流(CSV → 清理 → Parquet)
import polars as pl
# Extract
lf = pl.scan_csv(
"raw_data.csv",
dtypes={"id": pl.Int64, "date": pl.Utf8, "amount": pl.Float64},
)
# Transform
cleaned = (
lf
.with_columns(pl.col("date").str.to_date("%Y-%m-%d"))
.filter(pl.col("amount").is_not_null())
.with_columns(
year=pl.col("date").dt.year(),
month=pl.col("date").dt.month(),
amount_log=pl.col("amount").log(),
)
.drop_nulls()
)
# Load
cleaned.collect().write_parquet("clean_data.parquet", compression="zstd")
print("ETL complete")
2. 多源连接与聚合
import polars as pl
# Simulate three data sources
users = pl.DataFrame({
"uid": [1, 2, 3, 4],
"name": ["Alice", "Bob", "Charlie", "Diana"],
"region": ["East", "West", "East", "West"],
})
orders = pl.DataFrame({
"oid": range(1, 7),
"uid": [1, 1, 2, 3, 3, 3],
"amount": [100, 200, 150, 50, 75, 125],
})
products = pl.DataFrame({
"oid": range(1, 7),
"category": ["Elec", "Books", "Elec", "Books", "Elec", "Elec"],
})
# Join → aggregate
result = (
orders
.join(users, on="uid", how="left")
.join(products, on="oid", how="left")
.group_by("region", "category")
.agg(
pl.col("amount").sum().alias("total"),
pl.col("amount").mean().alias("avg_order"),
pl.len().alias("n_orders"),
)
.sort("total", descending=True)
)
print(result)
3. 时间序列特征工程
使用:GroupBy、窗口函数、连接、表达式 API。
- 使用
pl.scan_csv()或pl.scan_parquet()加载时间序列数据 - 解析日期:
.with_columns(pl.col("date").str.to_date()) - 按实体和日期排序:
.sort("entity_id", "date") - 添加滞后特征:
pl.col("value").shift(n).over("entity_id") - 添加滚动统计量:
pl.col("value").rolling_mean(window_size=7).over("entity_id") - 计算百分比变化:
(pl.col("value") - pl.col("value").shift(1)) / pl.col("value").shift(1) - 收集并写入:
.collect().write_parquet("features.parquet")
关键参数
| 参数 | 函数 | 默认值 | 范围/选项 | 作用 |
|---|---|---|---|---|
how | .join() | "inner" | inner、left、outer、cross、semi、anti | 联接类型 |
strategy | .join_asof() | "backward" | backward、forward、nearest | Asof 匹配方向 |
streaming | .collect() | False | True/False | 对大型数据分批处理 |
compression | .write_parquet() | "zstd" | snappy、gzip、brotli、lz4、zstd、uncompressed | Parquet 压缩 |
partition_by | .write_parquet() | None | 列列表 | Hive 风格分区 |
rechunk | pl.concat() | False | True/False | concat 后重新整理内存块 |
aggregate_function | .pivot() | "first" | first、sum、mean、max、min、count | 处理透视表中的重复值 |
n_rows | pl.read_csv() | None | 正整数 | 限制读取的行数(用于抽样) |
parallel | pl.read_csv() | "auto" | auto、columns、row_groups、none | 并行读取策略 |
dtypes | pl.read_csv() | None | 列名→类型的字典 | 覆盖类型推断 |
最佳实践
-
大型数据集使用惰性模式:使用
pl.scan_csv(),而不是pl.read_csv()。这样可以启用查询优化和流式处理。 -
使用表达式 API:避免使用
.map_elements()(会运行 Python,无法并行)。优先使用 Polars 原生操作——字符串、日期时间和列表命名空间可以满足大多数需求。 -
尽早选择列、尽早筛选:在惰性管道中尽可能靠前地放置
.select()和.filter()。优化器可以下推这些操作,但显式放置更有帮助。 -
低基数字符串使用 Categorical:
df.with_columns(pl.col("region").cast(pl.Categorical))——可大幅加快对重复字符串值进行分组和联接的速度。 -
优先使用 Parquet,而不是 CSV:Parquet 可保留类型、支持谓词下推,且文件体积可缩小 5–10 倍。使用
compression="zstd"可获得最佳的压缩率和速度平衡。 -
反模式——对行使用 Python 循环:绝不要使用
for row in df.iter_rows()迭代行来进行计算。请改用表达式。 -
反模式——连续调用
.with_columns():将多个列的添加操作合并到一次.with_columns()调用中,以便并行执行。
常见示例
示例:Pandas 迁移模式
import polars as pl
import pandas as pd
# Convert pandas → polars
pd_df = pd.DataFrame({"col": [1, 2, 3], "group": ["a", "b", "a"]})
pl_df = pl.from_pandas(pd_df)
# Key operation mapping:
# pandas: df["col"] → polars: df.select("col")
# pandas: df[df["col"] > 1] → polars: df.filter(pl.col("col") > 1)
# pandas: df.assign(x=...) → polars: df.with_columns(x=...)
# pandas: df.groupby().agg() → polars: df.group_by().agg()
# pandas: df.groupby().transform → polars: pl.col(...).over(...)
# pandas: df.merge() → polars: df.join()
# pandas: df.melt() → polars: df.unpivot()
# Convert back
pd_result = pl_df.to_pandas()
示例:复杂聚合报表
import polars as pl
df = pl.DataFrame({
"dept": ["Sales", "Eng", "Sales", "Eng", "Sales", "Eng"],
"level": ["Jr", "Sr", "Sr", "Jr", "Jr", "Sr"],
"salary": [50000, 95000, 75000, 70000, 55000, 100000],
})
report = (
df.group_by("dept", "level")
.agg(
pl.col("salary").mean().alias("avg_sal"),
pl.col("salary").median().alias("med_sal"),
pl.col("salary").std().alias("std_sal"),
pl.len().alias("count"),
)
.pivot(values="avg_sal", index="dept", columns="level")
.with_columns(
diff=pl.col("Sr") - pl.col("Jr"),
)
)
print(report)
示例:读取多个文件并对齐架构
import polars as pl
from pathlib import Path
# Read multiple CSVs with potentially different columns
files = sorted(Path("data/").glob("*.csv"))
dfs = [pl.read_csv(f) for f in files]
# Diagonal concat handles mismatched schemas (fills nulls)
combined = pl.concat(dfs, how="diagonal")
print(f"Combined: {combined.shape}")
print(f"Columns: {combined.columns}")
# Or use lazy scan for Parquet (automatic parallel)
lf = pl.scan_parquet("data/**/*.parquet")
result = lf.filter(pl.col("date") > "2023-01-01").collect()
故障排除
| 问题 | 原因 | 解决方案 |
|---|---|---|
SchemaError: column not found | 列名拼写错误或大小写不匹配 | 检查 df.columns;Polars 区分大小写 |
ComputeError: cannot cast | 操作中的类型不匹配 | 显式使用 .cast(pl.Type) |
collect 时出现 OutOfMemoryError | 数据量过大,不适合即时模式 | 使用 lf.collect(streaming=True),或先进行筛选 |
.map_elements() 速度慢 | Python UDF 阻止了并行处理 | 改用原生表达式(str/dt/list 命名空间) |
| 联接生成的行数超出预期 | 右侧 DataFrame 中存在重复键 | 先去重:df.unique(subset=["key"]) |
InvalidOperationError: join on different types | 键列的数据类型不同 | 将两列转换为相同类型:.cast(pl.Int64) |
.over() 返回的值不正确 | 忘记包含所有分组列 | 在 .over("col1", "col2") 中包含所有分组列 |
| Parquet 文件无法读取 | 写入时使用了不兼容的压缩方式 | 指定 compression="snappy" 以获得最高兼容性 |
| CSV 日期被读取为字符串 | CSV 读取器不会自动解析日期 | 读取后解析:pl.col("date").str.to_date("%Y-%m-%d") |
concat 因架构不同而失败 | 各 DataFrame 的列不匹配 | 使用 how="diagonal" 将缺失列填充为 null |
捆绑资源
-
references/pandas_migration.md— Pandas 到 Polars 迁移指南,包含操作映射表(选择、筛选、列操作、聚合、窗口函数、连接、重塑、字符串操作、日期时间操作、缺失数据、I/O)、互操作代码、常见迁移模式的并排代码示例、迁移陷阱和迁移检查清单。- 涵盖:原始 pandas_migration.md 中的所有操作映射内容
- 内联迁移:关键 Pandas 差异摘要 → SKILL.md「核心概念」中的「与 Pandas 的主要区别」部分;基本转换方案 → SKILL.md「常用方案」中的「Pandas 迁移模式」
- 省略:逐行迭代和顺序 pipe 的反模式代码示例——已在 io_best_practices.md 中介绍
-
references/advanced_operations.md— 滚动窗口(基于时间和基于行)、累积操作(cum_sum/max/min/prod)、带分组上下文的 shift/lag/lead、struct 操作(创建/访问/展开)、列表列操作(统计、eval、筛选、展开)、唯一值/重复值检测、高级排序(nulls_last、基于表达式、每组 top-N)、列重命名(字典、后缀/前缀/编程方式)、采样(固定 n、比例、bootstrap)、转置,以及高级重塑模式(宽-长-宽、嵌套 JSON 转扁平、多级 unpivot、水平拼接)。- 涵盖:原始 operations.md 中的高级操作,以及原始 transformations.md 中未纳入主 SKILL.md 的转换内容
- 内联迁移:基本选择/筛选 → SKILL.md「核心 API」第 1 节;groupby/聚合 → 第 2 节;基本连接/asof → 第 3 节;基本 pivot/unpivot/explode/concat → 第 4 节;字符串/日期/列表/条件基础操作 → 第 6 节;基本窗口函数 → 第 2 节
- 省略:连接性能提示(较简单,已在 SKILL.md「最佳实践」中介绍);拼接选项(rechunk 已列于「关键参数」表)
-
references/io_best_practices.md— 完整的 I/O 格式指南(CSV 选项、带分区的 Parquet 选项、JSON/NDJSON、Excel 多工作表、Arrow IPC)、数据库连接(PostgreSQL、MySQL、SQLite、BigQuery)、云存储(S3、Azure、GCS)、内存格式转换(dict、NumPy、pandas、Arrow)、格式选择决策指南、架构管理和错误处理、表达式组合与复用模式、列选择模式(按类型、正则表达式、排除)、内存管理(estimated_size、类型优化、流式处理)、用于可组合转换的管道函数、测试/调试(查询计划、架构验证、性能分析)、性能反模式(顺序 pipe、过多 DataFrame、原地修改、未指定类型)以及版本兼容性说明。- 涵盖:原始 io_guide.md 中的所有 I/O 内容、原始 best_practices.md 中的表达式/内存/测试/性能内容,以及原始 core_concepts.md 中的格式选择和版本说明
- 内联迁移:基本 CSV/Parquet/JSON/Excel/数据库读写 → SKILL.md「核心 API」第 5 节;惰性与急切模式对比 → SKILL.md「核心概念」表格;基本表达式上下文/语法 → SKILL.md 第 6 节;并行化/类型系统概念 → SKILL.md「核心概念」和「最佳实践」;空值处理 → SKILL.md 第 6 节;categorical 建议 → SKILL.md「最佳实践」第 4 项
- 省略:详细的表达式基础知识(什么是表达式、表达式上下文)——已在 SKILL.md「核心 API」中完整介绍;基本条件逻辑示例——已在 SKILL.md 第 6 节中介绍;基本聚合模式——已在第 2 节中介绍
各参考文件的处理方式(原始 6 个文件)
| 原始文件 | 行数 | 处理方式 | 目标 |
|---|---|---|---|
operations.md | 603 | 合并 | 高级操作 → references/advanced_operations.md;基础选择/筛选/groupby/窗口/字符串/日期 → SKILL.md Core API 第 1-2、6 节 |
transformations.md | 550 | 合并 | 重塑/转置 → references/advanced_operations.md;基础连接/pivot/unpivot/explode/concat → SKILL.md Core API 第 3-4 节 |
io_guide.md | 558 | 合并 | 完整的 I/O 详情 → references/io_best_practices.md;基础读写 → SKILL.md Core API 第 5 节 |
best_practices.md | 650 | 合并 | 表达式复用、内存、测试、反模式 → references/io_best_practices.md;核心最佳实践 → SKILL.md Best Practices |
core_concepts.md | 379 | 合并 | 格式选择、版本说明 → references/io_best_practices.md;数据类型、惰性/即时执行、并行处理 → SKILL.md Key Concepts |
pandas_migration.md | 418 | 迁移 | → references/pandas_migration.md(扩充了窗口/字符串/日期时间/缺失数据表格) |
有意省略的内容
- 行迭代示例(operations.md):不将其记录为一项正面能力;仅在 Best Practices 中作为反模式提及
- 表达式基础教程(core_concepts.md):SKILL.md Core API 第 1-4 节已完整涵盖表达式语法、上下文和扩展;单独的教程会造成重复
- 并行化内部细节(core_concepts.md):省略“哪些操作会并行化”列表——用户只需遵循 Best Practices 中关于使用表达式 API 的指导
- 写时复制对比(core_concepts.md):省略 Pandas 2.0+ 的写时复制详情——这些内容以迁移为重点,而非以 Polars 为中心
相关技能
- zarr-python — 分块数组存储;Polars 可以读写供 Zarr 处理的 Parquet
- matplotlib-scientific-plotting — 可视化;使用
.to_pandas()转换为 pandas 以进行绘图 - scikit-learn-machine-learning — ML 工作流;使用
.to_numpy()或.to_pandas()作为 sklearn 的输入
参考资料
- Polars 用户指南:https://docs.pola.rs/
- Polars API 参考:https://docs.pola.rs/api/python/stable/reference/
- GitHub:https://github.com/pola-rs/polars
- Polars 食谱:https://docs.pola.rs/user-guide/