
本文介绍使用 polars 的 selectors 和链式表达式,仅需几行代码即可高效追加“总计”和“百分比”两行,替代冗长的手动拼接逻辑,显著提升可读性与维护性。
本文介绍使用 polars 的 selectors 和链式表达式,仅需几行代码即可高效追加“总计”和“百分比”两行,替代冗长的手动拼接逻辑,显著提升可读性与维护性。
在 Polars 中为 DataFrame 动态添加统计汇总行(如列总和、占比)是常见需求,但若采用传统循环+拼接方式,不仅代码冗长,还容易出错且难以复用。幸运的是,Polars 提供了强大而声明式的 API——尤其是 selectors 模块与 pl.sum_horizontal() 等聚合函数,可大幅简化该流程。
以下是一个清晰、可复用的实现方案:
import polars as pl
import polars.selectors as cs
# 原始数据
df = pl.DataFrame({
"Col Ind": ["A", "B", "C", "D", "E"],
"Col A": [1, 2, 3, 4, 5],
"Col B": [2, 4, 6, 8, 10],
"Col C": [1, 3, 5, 7, 9],
"Col D": [5, 4, 3, 2, 1],
})
# 步骤 1:计算各数值列总和 → 单行 DataFrame
totals = df.select(cs.numeric().sum())
# 步骤 2:计算各列占总和的百分比(四舍五入取整)
total_sum = totals.sum_horizontal().item() # 所有数值列总和的标量值
percentage = totals.select(
(pl.all() * 100 / total_sum).round(0).cast(pl.Int64)
)
# 步骤 3:拼接原始表 + 总计行 + 百分比行,并插入标识列
result = pl.concat(
[
df,
totals.with_columns(pl.lit("Total").alias("Col Ind")),
percentage.with_columns(pl.lit("Percentage").alias("Col Ind")),
],
how="diagonal_relaxed"
)✅ 关键优势说明:
-
cs.numeric()自动识别所有数值列,无需硬编码列名,增强鲁棒性; -
sum_horizontal()高效计算跨列总和,避免手动sum()+full = sum(rowlist); -
pl.lit(...).alias("Col Ind")直接注入标签列,免去insert_column()或append()等易错操作; -
how="diagonal_relaxed"允许列类型自动对齐(如字符串列自动补null),避免concat类型冲突报错。
⚠️ 注意事项:
- 若原始 DataFrame 中存在非数值列(除
"Col Ind"外),cs.numeric()会自动跳过,确保安全; - 百分比计算中使用
.round(0).cast(pl.Int64)实现整数百分比;如需保留小数,可改为.round(1)并保留Float64类型; -
diagonal_relaxed是 Polars 0.20.0+ 推荐模式,兼容性优于旧版vertical拼接(后者要求严格 schema 匹配)。
最终输出包含 7 行:前 5 行为原始数据,第 6 行为 "Total" 及各列数值总和,第 7 行为 "Percentage" 及对应整数百分比(四舍五入),结构清晰、语义明确,真正实现「少写代码,多做事情」。

















