
本文详解如何在 Polars 中按 customer 和 product 分组,计算每组的总销售额(quantity × price 的行级乘积之和),并提供两种高效实现方式:标准 agg() 配合 sum() 与更简洁的 dot() 表达式。
本文详解如何在 polars 中按 customer 和 product 分组,计算每组的总销售额(quantity × price 的行级乘积之和),并提供两种高效实现方式:标准 `agg()` 配合 `sum()` 与更简洁的 `dot()` 表达式。
在数据分析中,常需将原始交易记录(如客户、商品、单价、数量)聚合为「客户 × 商品」维度的汇总指标——最典型的就是总销售额,即每笔交易的 quantity × price 之和。Polars 提供了高性能、声明式的表达方式来完成这一任务,关键在于正确组合行级计算与分组聚合。
✅ 正确做法:先计算行级金额,再分组求和
你的原始代码问题在于:
-
group_by(('customer', 'product'))语法虽可运行,但元组传参易出错,推荐显式使用字符串列表; -
.select(...)后直接.group_by(...)缺少聚合操作(如.sum()),导致结果未真正聚合,仅做分组但未压缩行数; -
pl.col('quantity').mul(pl.col('price'))生成的是中间列,必须通过.agg()显式指定其聚合方式。
✅ 方法一:显式乘积 + sum() 聚合(推荐初学者使用)
result = db.group_by(["customer", "product"]).agg(
total=(pl.col("quantity") * pl.col("price")).sum()
)该写法清晰表达了计算逻辑:对每行计算 quantity × price,再按 customer 和 product 分组,对每个组内所有行的乘积值求和。
✅ 方法二:使用 dot() —— 更简洁、语义更强
result = db.group_by("customer", "product").agg(
total=pl.col("quantity").dot("price")
)dot() 是 Polars 专为向量点积设计的高效方法,等价于 sum(a * b),且底层优化良好。它自动对齐同组内的两列并计算内积,代码更短、意图更明确,是处理“加权求和”类场景(如销售额、加权平均)的理想选择。
⚠️ 注意事项:
- 确保
quantity和price列均为数值类型(如Float64或Int64),否则dot()或乘法会报错;可用db = db.with_columns(pl.col("quantity", "price").cast(pl.Float64))统一转换。group_by(...).agg(...)返回的是新 LazyFrame(若原为 LazyFrame)或 DataFrame,结果自动包含customer、product和total三列,无需额外.select()。- 若需保留其他字段(如最早/最晚
sale_time),可在agg()中添加对应表达式,例如.agg(total=..., first_time=pl.col("sale_time").min())。
最终输出即为你所需的结构:每行唯一对应一个 (customer, product) 组合,total 列为该组合所有交易的销售金额总和,精准匹配业务需求。

















