Polars中按客户-产品分组计算销售总额的正确实现方法
Polars中按客户-产品分组计算销售总额的正确实现方法
看起来你已经找对了方向,但差了关键的一步聚合操作!咱们先理清楚问题:你想得到每个唯一客户-产品组合对应的总销售额,也就是把同一客户买同一产品的所有订单金额加起来对吧?
先看你提供的原始数据结构:
| customer | product | price | quantity | sale_time |
|---|---|---|---|---|
| C060235 | P0204 | 6.99 | 2 | 2024-03-11 08:24:11 |
| C045298 | P0167 | 14.99 | 1 | 2024-03-11 08:35:06 |
| ... | ... | ... | ... | ... |
| C039877 | P0024 | 126.95 | 1 | 2024-09-30 21:18:45 |
你想要的结果是这样的唯一组合加总:
| customer | product | total |
|---|---|---|
| C0000105 | P0168 | 643.78 |
| C0000105 | P0204 | 76.88 |
| ... | ... | ... |
| C1029871 | P1680 | 435.44 |
那你原来的代码问题出在哪呢?你已经计算出了每一行的订单金额(quantity * price),也指定了分组的列,但没有告诉Polars要对分组后的数据做什么聚合操作——也就是把每个组里的金额加起来。Polars的group_by之后必须用agg()方法来定义聚合逻辑,不然分组只是“分了组”,没有汇总结果。
下面给你两种正确的实现方式:
方式一:先计算单行金额再分组聚合
这种写法和你的思路最接近,先把每一行的销售金额算出来,再分组求和:
import polars as pl result = db.select( pl.col('customer'), pl.col('product'), # 计算每一行的销售金额,命名为line_total (pl.col('quantity') * pl.col('price')).alias('line_total') ).group_by(['customer', 'product']).agg( # 对每个分组的line_total求和,命名为total pl.col('line_total').sum().alias('total') )
方式二:更简洁的链式写法
Polars支持在agg()里直接计算并聚合,不用提前select,代码更紧凑:
import polars as pl result = db.group_by(['customer', 'product']).agg( # 直接在聚合步骤里计算总销售额:每行quantity*price后求和 total=(pl.col('quantity') * pl.col('price')).sum() )
这两种写法都会得到你想要的结果:每个客户-产品组合只出现一次,对应的total是该组合的所有订单金额之和。
如果之后你想对结果排序,比如按总销售额从高到低排列,可以在后面加个排序步骤:
result = db.group_by(['customer', 'product']).agg( total=(pl.col('quantity') * pl.col('price')).sum() ).sort('total', descending=True)
备注:内容来源于stack exchange,提问作者Scott Deerwester
相关产品推荐
相关产品推荐

