
本文介绍使用 Polars 的 group_by().agg() 配合布尔转换与 mean() 方法,高效计算每组中正值(≥0)在指定数值列中的占比。
本文介绍使用 polars 的 `group_by().agg()` 配合布尔转换与 `mean()` 方法,高效计算每组中正值(≥0)在指定数值列中的占比。
在数据聚合分析中,常需统计某类条件满足值的比例(如正值、非空、达标等)。Polars 提供了简洁而高性能的表达方式:利用 Expr.ge(0) 将数值列转为布尔掩码(True 表示 ≥0),再对布尔值取 mean() —— 因布尔型在数值上下文中自动映射为 1(True)和 0(False),其均值即等于 True 占比。
以下为完整实现示例:
import polars as pl
df = pl.DataFrame(
{
"group": ["A", "A", "A", "A", "A", "B", "B", "B", "B", "B"],
"value": [2, -1, 3, 1, -2, 1, 2, -1, 3, 2],
}
)
result = df.group_by("group").agg(
positive_percent = pl.col("value").ge(0).mean()
)
print(result)
输出结果为:
┌───────┬──────────────────┐ │ group ┆ positive_percent │ │ --- ┆ --- │ │ str ┆ f64 │ ╞═══════╪══════════════════╡ │ A ┆ 0.6 │ │ B ┆ 0.8 │ └───────┴──────────────────┘
✅ 关键原理说明:
-
pl.col("value").ge(0)生成布尔 Series([True, False, True, True, False]for group A); - 布尔 Series 的
mean()等价于sum() / len(),即True出现频率,完美对应“正值占比”; - 此方法无需
.filter()或显式计数,避免中间 DataFrame 构造,兼具可读性与性能优势。
⚠️ 注意事项:
- 若需严格统计“大于 0”(而非 ≥0),请改用
.gt(0); - 结果默认为
f64类型,如需百分比整数(如60而非0.6),可链式调用.mul(100).round(0).cast(pl.Int64); - 该逻辑天然支持空组处理(空组
mean()返回null),必要时可用.fill_null(0)补零。
此模式可轻松泛化至其他二元比例统计场景,例如:非空率(pl.col(...).is_not_null().mean())、达标率(pl.col(...).ge(threshold).mean())等,是 Polars 中推荐的惯用写法。










