事实核验:2026-08-16 · 状态:现行内容
记录仅说明核验时间与维护状态,不保证适用于所有环境;使用前请留意正文中的版本、适用条件与风险提示。
warning 适用边界与维护说明
本文适用于 Polars Python 表达式与 DataFrame 常用操作的入门学习,示例数据在正文中完整给出,不构成生产级数据处理或金额精度方案。实际使用需结合所安装版本核对 API,尤其是连接验证与 streaming 支持;金额类型、连接匹配率和日期解析失败率仍需按业务要求检查。本次仅作全文结构审阅,未执行示例、核验外部文档或检查链接可达性。
Polars表达式与常用数据操作
abstract 学习目标
用表达式而非逐行 Python 函数完成选择、过滤、派生列、分组、连接和空值处理;理解表达式与执行上下文的关系。
Polars 的核心不是“方法名字像 Pandas”,而是表达式 DSL。表达式描述一段列变换,本身不会独立产生结果;放入 select、with_columns、filter、group_by(...).agg(...) 等上下文后才按上下文执行。先阅读 Polars学习路线图。
1. 构造数据与查看 schema
import polars as pl
orders = pl.DataFrame(
{
"order_id": [1, 2, 3, 4],
"status": ["paid", "cancelled", "paid", None],
"amount": [99.0, 30.0, 120.0, 50.0],
"customer_id": [10, 20, 20, 30],
}
)
print(orders.schema)
预期能看到四列及其类型。实际项目应检查推断是否符合业务,尤其是金额、nullable integer、时间戳和分类列。相关数据结构可对照 Pandas数据结构。
2. select 与 with_columns
select 只返回指定表达式产生的列;with_columns 保留原列并新增或替换列。
summary = orders.select(
pl.len().alias("rows"),
pl.col("amount").sum().alias("amount_sum"),
pl.col("customer_id").n_unique().alias("customers"),
)
enriched = orders.with_columns(
(pl.col("amount") * 1.06).round(2).alias("amount_with_tax"),
pl.col("status").fill_null("unknown"),
)
预期 summary 为一行,rows=4、amount_sum=299.0、customers=3;enriched 保留四行并新增含税金额,同时填充状态空值。同一个 with_columns 中的表达式应按输入 schema 理解,不要依赖某个新列立即被旁边另一个表达式引用;需要有先后依赖时拆成两步。
3. filter 与条件表达式
paid = orders.filter(pl.col("status") == "paid")
flagged = orders.with_columns(
pl.when(pl.col("amount") >= 100)
.then(pl.lit("high"))
.otherwise(pl.lit("normal"))
.alias("amount_level")
)
预期 paid 只有订单 1、3;订单 3 被标记为 high。布尔条件中的空值不会自动等于 False 的业务含义,必须决定是过滤、填充还是单独保留未知状态。
4. 分组聚合
by_status = (
orders
.group_by("status")
.agg(
pl.len().alias("rows"),
pl.col("amount").sum().alias("amount_sum"),
pl.col("amount").mean().alias("amount_avg"),
)
.sort("status", nulls_last=True)
)
每个聚合表达式都在分组上下文中计算。group_by 不保证业务需要的输出顺序,因此展示或测试时应显式 sort。新增分组字段会改变粒度,必须重新核对唯一键与行数。
5. 连接与列名冲突
customers = pl.DataFrame(
{"customer_id": [10, 20], "segment": ["new", "vip"]}
)
joined = orders.join(
customers,
on="customer_id",
how="left",
validate="m:1",
)
validate="m:1" 表达多对一预期,能帮助发现右表重复键。预期客户 30 的 segment 为 null。真实任务还应检查连接前后行数和未匹配率;验证语义及 streaming 支持需按当前 API 文档复查。
6. 字符串、日期与空值
events = pl.DataFrame(
{"raw_time": ["2026-08-16 10:00:00", None], "code": [" a ", "B"]}
).with_columns(
pl.col("raw_time").str.to_datetime(strict=False).alias("event_time"),
pl.col("code").str.strip_chars().str.to_uppercase().alias("code_clean"),
)
strict=False 会把无法解析的值转为 null,适合探索但可能掩盖脏数据。生产处理应额外统计“原值非空但解析后为空”的数量。系统化清洗见 Pandas数据清洗。
7. 避免 Python UDF
优先使用原生表达式,因为 Polars 可以分析、并行化和优化它们。map_elements 等 Python UDF 通常更慢,也可能限制优化。只有原生表达式确实无法表达、并且有性能基准和返回类型测试时才使用。
8. 练习与验收
- 为订单增加折扣后金额,禁止使用
apply或 Python 循环。 - 按客户聚合 GMV 和订单数,显式排序并写预期结果。
- 制造重复客户维表,用连接验证发现违反
m:1。 - 解析一列混合日期,统计失败率并保留原始字段。
- 对金额列比较
Float64与 Decimal 的 schema 和结果。
9. 延伸阅读
- Lazy执行与性能优化
- 从Pandas迁移到Polars
- DuckDB学习路线图
- DuckDB直接查询文件
- DuckDB Python集成
- DuckDB性能优化
- Ibis学习路线图
- Ibis表达式
- Ibis后端连接
- Ibis跨后端测试
- Pandas数据操作
- Python数据读取与存储
- Python特征工程
- SQL学习路线图