mcpField
P
polars

polars

github.com/crazymsn数据与数据库2336 次安装22 周前更新
代码仓库

关于 polars

Polars 是面向 Python 和 Rust 的 DataFrame 库,适用于数据处理与分析工作流。它以表达式 API 和惰性查询优化支持高效转换大型数据集。

主要功能

  1. 01基于表达式的数据转换
  2. 02惰性查询规划与优化
  3. 03并行数据操作
  4. 04读写常见数据格式
  5. 05连接、聚合与重塑数据
  6. 06pandas 迁移指南

适用场景

  1. 01筛选和聚合大型数据集
  2. 02构建优化的数据管道
  3. 03在文件格式间转换数据
  4. 04将 pandas 操作迁移到 Polars

安装

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

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

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

包含的文件

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

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

详细介绍

Polars

概述

Polars 是一个基于 Apache Arrow 构建的、速度极快的 Python 和 Rust DataFrame 库。使用 Polars 基于表达式的 API、惰性求值框架和高性能数据操作能力,可高效进行数据处理、从 pandas 迁移以及数据管道优化。

快速开始

安装与基本用法

安装 Polars:

uv pip install polars

基本的 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

选择并操作列:

# 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$"))
Filter

按条件筛选行:

# 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")
)
With Columns

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

# 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,
)
Group By 与聚合

对数据分组并计算聚合:

# 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:更快,但会将行分组在一起
  • 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。

转换

连接(Join)

合并 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")
拼接(Concatenation)

堆叠 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)
df.pivot(values="sales", index="date", columns="product")

# 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。

最佳实践

性能优化
  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(streaming=True)
    
  4. 尽早只选择需要的列:

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

    • 对低基数(low-cardinality)字符串使用 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