Polars中计算DataFrame分组百分比计数的最佳方法
Polars 分组占比统计最优实现
你原来的写法逻辑成立,但存在冗余步骤,可以用Polars原生能力简化,同时获得更好的执行效率、降低代码出错概率。
方案1:最简写法(单字段占比统计首选)
Polars内置的value_counts方法原生支持归一化占比计算,是这类单字段频次占比需求的最优选择,底层做了专门的计数性能优化:
import polars as pl df = pl.DataFrame({"person": ["a", "a", "b"], "value": [1, 2, 3]}) result = df["person"].value_counts(normalize=True).rename({"proportion": "percent"})
运行后直接返回你需要的结果结构,和示例输出完全一致。
方案2:通用聚合写法(多指标计算场景适用)
如果你需要在分组统计时同时计算其他聚合指标(比如同步统计value列的均值、总和等),可以用链式表达式完成全流程计算,不需要提前构造辅助列,也不需要手动维护总行数变量:
result = ( df .group_by("person") .agg( pl.count().alias("cnt"), pl.col("value").mean().alias("value_avg") # 其他需要的聚合指标可直接追加 ) .with_columns(percent = pl.col("cnt") / pl.col("cnt").sum()) .drop("cnt") )
如果只需要统计占比不需要其他指标,还可以进一步简化:
result = ( df .group_by("person") .agg(pl.count().alias("percent")) .with_columns(percent = pl.col("percent") / pl.col("percent").sum()) )
写法优势
- 不需要额外构造全1的辅助列,
pl.count()直接统计分组行数,少了一步不必要的列计算逻辑 - 不需要提前手动计算、维护总行数变量,就算你在分组前加了过滤、去重等逻辑,占比计算会自动基于处理后的数据集生效,不会因为忘记更新总行数出现计算错误
- 所有逻辑在同一个表达式链中完成,符合Polars的惰性执行设计,Polars会自动优化执行计划,性能优于穿插Python层变量计算的写法
注意:Polars的
group_by默认不会对结果排序,如果需要按占比降序、或者按分组字段排序,在最后追加对应的排序逻辑即可,比如.sort("percent", descending=True)。
内容的提问来源于stack exchange,提问作者mark0512
相关产品推荐
相关产品推荐

