
本文介绍如何使用 polars 对销售数据按 customer 和 product 组合进行分组,并准确计算每组的总销售额(quantity × price 的行级乘积之和)。
本文介绍如何使用 polars 对销售数据按 customer 和 product 组合进行分组,并准确计算每组的总销售额(quantity × price 的行级乘积之和)。
在数据分析中,常需将原始交易记录聚合为“客户–商品”维度的汇总指标。例如,给定包含 customer、product、price 和 quantity 的销售表,目标是生成每个唯一 (customer, product) 对应的 总销售额(即该客户购买该商品所有订单的 price × quantity 之和)。
关键在于:先逐行计算销售金额,再按多列分组并求和。你原代码的问题在于:
-
group_by(('customer', 'product'))语法不正确(Polars 不接受元组作为 group_by 参数); - 缺少聚合操作(
.agg()),仅分组不会产生标量结果; - 未对
quantity × price的结果执行.sum()。
✅ 正确做法如下:
✅ 方法一:显式乘积 + .sum() 聚合(推荐,清晰易读)
import polars as pl
result = db.group_by(["customer", "product"]).agg(
total=(pl.col("quantity") * pl.col("price")).sum()
)✅ 方法二:使用 .dot()(简洁高效,专为向量内积设计)
result = db.group_by("customer", "product").agg(
total=pl.col("quantity").dot("price")
)?
dot()等价于sum(pl.col("a") * pl.col("b")),但底层优化更高效,且语义明确——适用于“加权求和”场景(如销售额、加权平均等)。
⚠️ 注意事项
-
group_by()接受字符串列表(如["customer", "product"])或多个字符串参数(如"customer", "product"),不可传入元组; - 所有聚合表达式必须包裹在
.agg()中,否则分组后无实际计算; - 若存在缺失值(
null),*和.dot()均会自动跳过(类似sum(skip_nulls=True)),如需不同空值策略,可显式链式调用.fill_null(0); - 结果默认不排序;如需按
customer或total排序,追加.sort("customer")或.sort("total", descending=True)。
✅ 验证输出结构
运行后 result 将是一个三列 Polars DataFrame:
| customer | product | total |
|-----------|---------|--------|
| C0000105 | P0168 | 643.78 |
| C0000105 | P0204 | 76.88 |
| ... | ... | ... |
这正是你所需的“唯一客户–商品对 → 总销售额”汇总表。掌握这一模式,可轻松扩展至多维分组(如增加 sale_time.dt.month() 按月统计)或复合指标(如同时计算 sum, count, mean)。

















