Polars:分组统计时如何保留cut生成的所有分箱(含空值)
Polars分箱后保留所有区间(含无数据分箱)的实现方法
核心思路
要实现分箱后保留0-100步长10的全部区间,无数据分箱计数为null,关键是先定义完整的分箱集合,再通过左连接补全无数据的分箱。
代码实现
- 导入Polars并创建示例DataFrame
import polars as pl # 示例数据:仅包含部分区间的数值 df = pl.DataFrame({ "a": [5, 12, 25, 33, 55, 70, 95] })
- 生成完整分箱并添加分箱列
手动指定0-100、步长10的分箱边界,确保cut方法生成我们需要的所有区间:
# 定义分箱边界:0,10,...,100 bins = list(range(0, 101, 10)) # 对列a分箱,得到cut_a列 df_with_cut = df.with_columns( cut_a=pl.col("a").cut(bins=bins, include_lowest=True) )
- 创建包含所有分箱的基准表
生成一个包含所有目标分箱的DataFrame,作为后续补全的基准:
all_bins_df = pl.DataFrame({ "cut_a": pl.cut(pl.Series(bins[:-1]), bins=bins, include_lowest=True).unique() })
- 分组统计并补全无数据分箱
先统计有数据分箱的数量,再通过左连接基准表,保留所有分箱并将无数据分箱的计数设为null:
# 统计有数据的分箱数量 count_df = df_with_cut.group_by("cut_a").agg( count=pl.count() ) # 左连接补全所有分箱 result = all_bins_df.join(count_df, on="cut_a", how="left") # 输出结果 print(result)
输出示例
shape: (10, 2) ┌─────────────┬───────┐ │ cut_a ┆ count │ │ --- ┆ --- │ │ interval[i64] ┆ i64 │ ╞═════════════╪═══════╡ │ [0, 10) ┆ 1 │ │ [10, 20) ┆ 1 │ │ [20, 30) ┆ 1 │ │ [30, 40) ┆ 1 │ │ [40, 50) ┆ null │ │ [50, 60) ┆ 1 │ │ [60, 70) ┆ null │ │ [70, 80) ┆ 1 │ │ [80, 90) ┆ null │ │ [90, 100] ┆ 1 │ └─────────────┴───────┘
内容的提问来源于stack exchange,提问作者blaylockbk
相关产品推荐
相关产品推荐

