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

Python Polars分组时如何忽略空值/NULL值列?

问题描述

现有如下Polars DataFrame:

df = pl.DataFrame({
    'last_name':['James','Warner','Marino','James','Warner','Marino','James'],
    'first_name':['Horn','Bro','Kach','Horn','Bro','Kach','Horn'],
    'dob':['03/06/1990','09/16/1990','03/06/1990','','03/06/1990','','']
})

对last_name、first_name和dob列分组统计数量:

df.group_by('last_name','first_name','dob').len()

得到结果:

shape: (6, 4)
┌───────────┬────────────┬────────────┬─────┐
│ last_name ┆ first_name ┆ dob        ┆ len │
│ ---       ┆ ---        ┆ ---        ┆ --- │
│ str       ┆ str        ┆ str        ┆ u32 │
╞═══════════╪════════════╪════════════╪═════╡
│ Warner    ┆ Bro        ┆ 09/16/1990 ┆ 1   │
│ Marino    ┆ Kach       ┆ 03/06/1990 ┆ 1   │
│ Marino    ┆ Kach       ┆            ┆ 1   │
│ James     ┆ Horn       ┆            ┆ 2   │ # 不符合预期
│ James     ┆ Horn       ┆ 03/06/1990 ┆ 1   │
│ Warner    ┆ Bro        ┆ 03/06/1990 ┆ 1   │
└───────────┴────────────┴────────────┴─────┘

需求是分组时忽略分组列中的空值/空字符串,比如James Horn的两条空dob记录不应被纳入分组,预期输出:

shape: (4, 4)
┌───────────┬────────────┬────────────┬─────┐
│ last_name ┆ first_name ┆ dob        ┆ len │
│ ---       ┆ ---        ┆ ---        ┆ --- │
│ str       ┆ str        ┆ str        ┆ u32 │
╞═══════════╪════════════╪════════════╪═════╡
│ Warner    ┆ Bro        ┆ 03/06/1990 ┆ 1   │
│ James     ┆ Horn       ┆ 03/06/1990 ┆ 1   │
│ Marino    ┆ Kach       ┆ 03/06/1990 ┆ 1   │
│ Warner    ┆ Bro        ┆ 09/16/1990 ┆ 1   │
└───────────┴────────────┴────────────┴─────┘

目前可以通过先过滤再分组实现:

df.filter(pl.col.dob != '').group_by('last_name','first_name','dob').len()

但如果有10个分组列需要过滤,手动逐个编写条件会很繁琐,有没有更简便的方案?


解决方案

方法1:批量过滤所有分组列的空字符串

先定义分组列的列表,再用pl.all批量生成过滤条件,确保所有分组列都不为空字符串:

group_cols = ['last_name', 'first_name', 'dob']
df.filter(pl.all(group_cols) != '').group_by(group_cols).len()

如果你的空值是Polars原生的null(而非空字符串),可以改用is_not_null():

df.filter(pl.all(group_cols).is_not_null()).group_by(group_cols).len()

方法2:统一转换空值后批量删除

先把分组列中的空字符串转为null,再一次性删除包含null的行,最后分组统计:

group_cols = ['last_name', 'first_name', 'dob']
(df.with_columns(pl.col(group_cols).str.strip().replace('', None))
   .drop_nulls(subset=group_cols)
   .group_by(group_cols)
   .len())

这里的str.strip()用于处理可能存在的空白字符串(比如' '),如果确定没有这类情况可以省略。

方法3:分组后过滤(效率较低,不推荐)

如果不想提前过滤,也可以先完成分组统计,再过滤掉包含空字符串的分组结果,但这种方式会先对所有行分组,再做过滤,效率不如提前过滤:

(df.group_by('last_name','first_name','dob').len()
   .filter(pl.all(['last_name','first_name','dob']) != ''))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 09:10:44