You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Polars中如何实现按列分组动态统计指定列的空值占比?

在Polars中实现动态分组统计空值占比的方法

问题描述

我需要在Polars DataFrame中按指定列分组,统计另一组指定列的空值占比。由于DataFrame的列可能会变化,希望能通过传入分组列列表和待统计空值的列列表来动态实现。目前分组可以直接传列列表,但统计空值时只能逐列写代码,写法如下:

df = df.group_by(list_of_grouping_fields)\
    .agg(
        pl.len().alias('Row_Count'),
        pl.col("INVOICE NUMBER").null_count().alias('INVOICENUMBER_nullcount'),
        pl.col("ORDER NUMBER").null_count().alias('ORDERNUMBER_nullcount')
        )

这种写法效率低,列变化时还要修改代码。理想写法是能直接传入列列表和别名列表来动态聚合:

df = df.group_by(list_of_grouping_fields)\
    .agg(
        pl.len().alias('Row_Count'),
        pl.col([list_of_agg_fields]).null_count().alias([list_of_aliases])
        )

请问Polars中有没有方法实现这种动态聚合?

解决方案

Polars支持通过动态生成表达式列表实现这种需求,无需逐列硬编码。可以通过列表推导式生成每个目标列的空值计数和占比表达式,再传入agg()方法。

步骤1:准备数据与参数

先定义分组列、待统计列,以及示例DataFrame:

import polars as pl

# 示例数据
df = pl.DataFrame({
    "GROUP_COL1": ["A", "A", "B", "B", "A"],
    "GROUP_COL2": ["X", "Y", "X", "X", "Y"],
    "INVOICE NUMBER": [123, None, 456, None, 789],
    "ORDER NUMBER": [None, 987, 654, None, None]
})

list_of_grouping_fields = ["GROUP_COL1", "GROUP_COL2"]
list_of_agg_fields = ["INVOICE NUMBER", "ORDER NUMBER"]

步骤2:动态生成聚合表达式

利用列表推导式,为每个待统计列生成空值计数、空值占比(空值数/总条数)的表达式,并自定义别名:

# 初始化表达式列表,先加入总行数统计
agg_exprs = [pl.len().alias('Row_Count')]

# 为每个目标列添加空值计数和占比表达式
for col in list_of_agg_fields:
    # 自定义别名规则:去掉空格+小写+后缀
    count_alias = col.replace(" ", "").lower() + "_nullcount"
    ratio_alias = col.replace(" ", "").lower() + "_nullratio"
    
    agg_exprs.extend([
        pl.col(col).null_count().alias(count_alias),
        (pl.col(col).null_count() / pl.len()).alias(ratio_alias)
    ])

步骤3:执行分组聚合

将生成的表达式列表传入agg()方法即可完成动态聚合:

result_df = df.group_by(list_of_grouping_fields).agg(agg_exprs)
print(result_df)

输出结果

shape: (3, 7)
┌────────────┬────────────┬───────────┬──────────────────────┬──────────────────────┬─────────────────────┬─────────────────────┐
│ GROUP_COL1 ┆ GROUP_COL2 ┆ Row_Count ┆ invoicenumber_nullco ┆ invoicenumber_nullra ┆ ordernumber_nullcou ┆ ordernumber_nullrat │
│ ---        ┆ ---        ┆ ---       ┆ unt                  ┆ tio                  ┆ nt                  ┆ io                  │
│ str        ┆ str        ┆ u32       ┆ ---                  ┆ ---                  ┆ ---                  ┆ ---                  │
│            ┆            ┆           ┆ u32                  ┆ f64                  ┆ u32                  ┆ f64                  │
╞════════════╪════════════╪═══════════╪══════════════════════╪══════════════════════╪═════════════════════╪═════════════════════╡
│ A          ┆ X          ┆ 1         ┆ 0                    ┆ 0.0                  ┆ 1                    ┆ 1.0                 │
│ A          ┆ Y          ┆ 2         ┆ 1                    ┆ 0.5                  ┆ 1                    ┆ 0.5                 │
│ B          ┆ X          ┆ 2         ┆ 1                    ┆ 0.5                  ┆ 1                    ┆ 0.5                 │
└────────────┴────────────┴───────────┴──────────────────────┴──────────────────────┴─────────────────────┴─────────────────────┘

简化写法

如果不需要复杂的别名规则,也可以用一行代码生成表达式:

agg_exprs = [
    pl.len().alias('Row_Count'),
    *[pl.col(col).null_count().alias(f"{col.replace(' ', '')}_nullcount") for col in list_of_agg_fields],
    *[(pl.col(col).null_count() / pl.len()).alias(f"{col.replace(' ', '')}_nullratio") for col in list_of_agg_fields]
]

result_df = df.group_by(list_of_grouping_fields).agg(agg_exprs)

关键说明

  • Polars的agg()方法接受表达式列表,只要动态生成该列表就能实现动态聚合。
  • 别名规则可根据需求自定义,比如保留空格、使用不同后缀等。
  • 若仅需要空值计数,去掉占比相关表达式即可。

内容的提问来源于stack exchange,提问作者DixieFlatline

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 20:50:28