mcpField
A
alterlab-polars

alterlab-polars

github.com/alterlab-ieu数据与数据库7866 次安装5 周前更新
代码仓库

关于 alterlab-polars

此 Skill 介绍如何使用 Python 和 Rust 的 DataFrame 库 Polars 处理表格数据,涵盖表达式转换与惰性查询优化,也涉及 pandas 迁移和单机数据管道。

主要功能

  1. 01使用表达式构建数据转换
  2. 02优化惰性查询计划
  3. 03读写常见数据格式
  4. 04执行连接、聚合和重塑
  5. 05提供 pandas 迁移指导

适用场景

  1. 01加速单机上的 pandas 工作流
  2. 02通过惰性扫描构建 ETL 管道
  3. 03聚合并连接大型内存表

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/alterlab-ieu/alterlab-academic-skills --skill alterlab-polars

安装后在 Claude Code 中输入/alterlab-polars确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

evals/
evals.json
references/
best_practices.md
core_concepts.md
io_guide.md
operations.md
pandas_migration.md
transformations.md

详细介绍

Polars

概述

Polars 是一个基于 Apache Arrow 构建的极速 DataFrame 库,支持 Python 和 Rust。使用 Polars 基于表达式的 API、惰性求值框架和高性能数据处理功能,高效完成数据处理、pandas 迁移和数据管道优化。

何时使用此技能

  • pandas 代码运行太慢,但数据(或惰性查询涉及的列)可以装入一台机器
  • 使用惰性扫描(scan_csv、scan_parquet)和查询优化构建 ETL 或特征处理管道
  • 将 pandas 代码迁移到 Polars 表达式 API
  • 对大型内存表使用窗口函数、连接和分组聚合
不适用的场景
场景改用
在集群中进行分布式执行,或使用任务调度器和仪表板扩展现有的 pandas/NumPy 代码alterlab-dask
使用内存映射 HDF5/Arrow 文件进行十亿行的外存探索和大数据绘图alterlab-vaex
初步了解不熟悉的数据文件:结构、缺失情况和质量报告alterlab-eda

快速开始

安装和基本用法

固定使用较新的 1.x 版本(此处示例使用 Polars 1.x API):

uv add 'polars>=1.0,<2'

Polars 2.0 目前处于候选发布版阶段(2.0.0rc2,2026 年 9 月)。其升级指南列出了可能静默改变结果的变更:LazyFrame.collect() 默认使用流式引擎(部分连接/逆透视操作的行顺序可能改变),pl.concat(how="horizontal") 要求高度相同(how="horizontal_extend" 会进行填充),explode() 会丢弃空列表,而不是输出空值行,is_in 会拒绝有损类型转换,LazyFrame.profile() 已移除,无表头 CSV 的列名将根据 column_0 命名。升级到 2.x 前,请查看 https://docs.pola.rs/releases/upgrade/。

基本的 DataFrame 创建和操作:

import polars as pl

# Create DataFrame
df = pl.DataFrame({
    "name": ["Alice", "Bob", "Charlie"],
    "age": [25, 30, 35],
    "city": ["NY", "LA", "SF"]
})

# Select columns
df.select("name", "age")

# Filter rows
df.filter(pl.col("age") > 25)

# Add computed columns
df.with_columns(
    age_plus_10=pl.col("age") + 10
)

核心概念

表达式

表达式是 Polars 操作的基本构件。它们描述对数据的转换,可组合、复用和优化。

关键原则:

  • 使用 pl.col("column_name") 引用列
  • 链接方法以构建复杂转换
  • 表达式采用惰性求值,仅在上下文中执行(select、with_columns、filter、group_by)

示例:

# Expression-based computation
df.select(
    pl.col("name"),
    (pl.col("age") * 12).alias("age_in_months")
)
惰性求值与即时求值

即时求值(DataFrame): 操作会立即执行

df = pl.read_csv("file.csv")  # Reads immediately
result = df.filter(pl.col("age") > 25)  # Executes immediately

惰性求值(LazyFrame): 操作会构建查询计划,并在执行前进行优化

lf = pl.scan_csv("file.csv")  # Doesn't read yet
result = lf.filter(pl.col("age") > 25).select("name", "age")
df = result.collect()  # Now executes optimized query

何时使用惰性求值:

  • 处理大型数据集
  • 处理复杂查询管道
  • 只需要部分列/行时
  • 性能至关重要时

惰性求值的优点:

  • 自动查询优化
  • 谓词下推
  • 投影下推
  • 并行执行

如需了解详细概念,请加载 references/core_concepts.md。

常见操作

选择

选择和处理列:

# Select specific columns
df.select("name", "age")

# Select with expressions
df.select(
    pl.col("name"),
    (pl.col("age") * 2).alias("double_age")
)

# Select all columns matching a pattern
df.select(pl.col("^.*_id$"))
筛选

根据条件筛选行:

# Single condition
df.filter(pl.col("age") > 25)

# Multiple conditions (cleaner than using &)
df.filter(
    pl.col("age") > 25,
    pl.col("city") == "NY"
)

# Complex conditions
df.filter(
    (pl.col("age") > 25) | (pl.col("city") == "LA")
)
添加列

添加或修改列,同时保留现有列:

# Add new columns
df.with_columns(
    age_plus_10=pl.col("age") + 10,
    name_upper=pl.col("name").str.to_uppercase()
)

# Parallel computation (all columns computed in parallel)
df.with_columns(
    pl.col("value") * 10,
    pl.col("value") * 100,
)
分组和聚合

对数据分组并计算聚合值:

# Basic grouping
df.group_by("city").agg(
    pl.col("age").mean().alias("avg_age"),
    pl.len().alias("count")
)

# Multiple group keys
df.group_by("city", "department").agg(
    pl.col("salary").sum()
)

# Conditional aggregations
df.group_by("city").agg(
    (pl.col("age") > 30).sum().alias("over_30")
)

如需了解详细的操作模式,请加载 references/operations.md。

聚合和窗口函数

聚合函数

group_by 上下文中的常见聚合:

  • pl.len() - 统计行数
  • pl.col("x").sum() - 求和
  • pl.col("x").mean() - 求平均值
  • pl.col("x").min() / pl.col("x").max() - 求最小值/最大值
  • pl.first() / pl.last() - 获取首个/最后一个值
使用 over() 的窗口函数

应用聚合,同时保留行数:

# Add group statistics to each row
df.with_columns(
    avg_age_by_city=pl.col("age").mean().over("city"),
    rank_in_city=pl.col("salary").rank().over("city")
)

# Multiple grouping columns
df.with_columns(
    group_avg=pl.col("value").mean().over("category", "region")
)

映射策略:

  • group_to_rows(默认):保留原始行顺序
  • explode:改变行数(在 select 中使用,而非 with_columns);输出按组排列
  • join:创建列表列

数据 I/O

支持的格式

Polars 支持读取和写入:

  • CSV、Parquet、JSON、Excel
  • 数据库(通过连接器)
  • 云存储(S3、Azure、GCS)
  • Google BigQuery
  • 多个文件/分区文件
常见 I/O 操作

CSV:

# Eager
df = pl.read_csv("file.csv")
df.write_csv("output.csv")

# Lazy (preferred for large files)
lf = pl.scan_csv("file.csv")
result = lf.filter(...).select(...).collect()

Parquet(性能更佳,推荐使用):

df = pl.read_parquet("file.parquet")
df.write_parquet("output.parquet")

JSON:

df = pl.read_json("file.json")
df.write_json("output.json")

如需完整的 I/O 文档,请加载 references/io_guide.md。

转换

连接

合并 DataFrame:

# Inner join
df1.join(df2, on="id", how="inner")

# Left join
df1.join(df2, on="id", how="left")

# Join on different column names
df1.join(df2, left_on="user_id", right_on="id")
拼接

堆叠 DataFrame:

# Vertical (stack rows)
pl.concat([df1, df2], how="vertical")

# Horizontal (add columns)
pl.concat([df1, df2], how="horizontal")

# Diagonal (union with different schemas)
pl.concat([df1, df2], how="diagonal")
透视与逆透视

重塑数据:

# Pivot (wide format): on= is the column whose values become new columns
df.pivot("product", index="date", values="sales")

# Unpivot (long format)
df.unpivot(index="id", on=["col1", "col2"])

如需详细的转换示例,请加载 references/transformations.md。

从 Pandas 迁移

Polars 相较于 pandas 性能提升显著,且 API 更简洁。主要区别:

概念区别
  • 没有索引:Polars 仅使用整数位置
  • 严格类型:不会静默转换类型
  • 惰性求值:可通过 LazyFrame 使用
  • 默认并行:操作会自动并行执行
常见操作映射
操作PandasPolars
选择列df["col"]df.select("col")
筛选df[df["col"] > 10]df.filter(pl.col("col") > 10)
添加列df.assign(x=...)df.with_columns(x=...)
分组df.groupby("col").agg(...)df.group_by("col").agg(...)
窗口df.groupby("col").transform(...)df.with_columns(...).over("col")
关键语法模式

Pandas 顺序执行(较慢):

df.assign(
    col_a=lambda df_: df_.value * 10,
    col_b=lambda df_: df_.value * 100
)

Polars 并行执行(较快):

df.with_columns(
    col_a=pl.col("value") * 10,
    col_b=pl.col("value") * 100,
)

如需完整的迁移指南,请加载 references/pandas_migration.md。

最佳实践

Polars 1.x API 注意事项(自 0.x 更名)

以下旧名称会出现在过时教程和大模型训练数据中;请使用 1.x 形式:

  • read_csv(dtypes=...) -> read_csv(schema_overrides=...)
  • pl.Utf8 -> pl.String
  • pl.NUMERIC_DTYPES -> import polars.selectors as cs; cs.numeric()
  • join(how="outer") -> join(how="full")(且 how="full" 不再合并键;如需恢复旧行为,请传入 coalesce=True)
  • pivot(columns=...) -> pivot(on=...)(on 是第一个位置参数)
  • collect(streaming=True) -> collect(engine="streaming")
  • read_database(connection_uri=...) -> read_database_uri(uri=...)
性能优化
  1. 对大型数据集使用惰性求值:

    lf = pl.scan_csv("large.csv")  # Don't use read_csv
    result = lf.filter(...).select(...).collect()
    
  2. 避免在热点路径中使用 Python 函数:

    • 使用表达式 API,以实现并行化
    • 仅在必要时使用 .map_elements()
    • 优先使用原生 Polars 操作
  3. 使用流式引擎降低峰值内存:

    lf.collect(engine="streaming")  # `streaming=True` is deprecated
    
  4. 尽早仅选择所需列:

    # Good: Select columns early
    lf.select("col1", "col2").filter(...)
    
    # Bad: Filter on all columns first
    lf.filter(...).select("col1", "col2")
    
  5. 使用恰当的数据类型:

    • 对低基数字符串使用 Categorical
    • 选择合适的整数大小(i32 或 i64)
    • 对时间数据使用日期类型
表达式模式

条件操作:

pl.when(condition).then(value).otherwise(other_value)

对多个列执行列操作:

df.select(pl.col("^.*_value$") * 2)  # Regex pattern

空值处理:

pl.col("x").fill_null(0)
pl.col("x").is_null()
pl.col("x").drop_nulls()

如需更多最佳实践和模式,请加载 references/best_practices.md。

资源

此技能包含全面的参考文档:

references/
  • core_concepts.md - 详细说明表达式、惰性求值和类型系统
  • operations.md - 所有常见操作的完整指南及示例
  • pandas_migration.md - 从 pandas 迁移到 Polars 的完整指南
  • io_guide.md - 所有支持格式的数据 I/O 操作
  • transformations.md - 连接、拼接、透视和重塑操作
  • best_practices.md - 性能优化技巧和常见模式

当用户需要了解特定主题的详细信息时,按需加载这些参考文档。

评论

支持 Markdown