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

Polars中如何删除某列同值分组内的无效数据行(当分组存在有效数据时)

Polars中如何删除某列同值分组内的无效数据行(当分组存在有效数据时)

嘿,我来帮你搞定这个分组过滤的问题!先理清楚你的需求:你有一个按name分组的DataFrame,对于每个分组,如果里面存在found='yes'的有效行,就只保留这个有效行,把同组里found='no'的无效行删掉;如果整个分组里全是无效行(比如name='b'的组),那就把这个组的所有行都保留下来,对吧?

先看看你给出的原始数据,用代码还原一下:

import polars as pl

df = pl.DataFrame({
    'name': ['a', 'a', 'b', 'b'],
    'found': ['yes', 'no', 'no', 'no'],
    'found_in_iteration': ['1', 'not_found', 'not_found', 'not_found']
})

接下来给你两种靠谱的解决方法,你可以根据自己的习惯选:

方法一:用窗口函数(性能优先)

这种方法用Polars的窗口函数做向量化操作,大数据量下速度更快,代码也简洁:

result = df.filter(
    # 保留本身是有效行的记录
    pl.col('found') == 'yes' 
    # 或者,当前分组没有任何有效行时,保留所有行
    | ~pl.col('found').eq('yes').any().over('name')
)

运行后得到的结果是:

shape: (3, 3)
┌──────┬───────┬────────────────────┐
│ name ┆ found ┆ found_in_iteration │
│ ---  ┆ ---   ┆ ---                │
│ str  ┆ str   ┆ str                │
╞══════╪═══════╪════════════════════╡
│ a    ┆ yes   ┆ 1                  │
│ b    ┆ no    ┆ not_found          │
│ b    ┆ no    ┆ not_found          │
└──────┴───────┴────────────────────┘

给你拆解下逻辑:

  • pl.col('found').eq('yes').any().over('name'):这部分会给每个name分组标记一个布尔值——如果组里有至少一个found='yes'的行,就返回True,否则False,而且组里的每一行都会带上这个标记。
  • 过滤条件就很清晰了:要么行本身是有效行,要么该组没有任何有效行,这两种情况我们都保留。

方法二:分组后单独处理(直观易懂)

如果你觉得窗口函数有点绕,也可以用分组后逐个处理的方式,逻辑更直白:

result = df.group_by('name').map(
    lambda group: 
    # 如果当前组有有效行,就只保留有效行
    group.filter(pl.col('found') == 'yes') 
    # 否则直接返回整个组
    if group['found'].eq('yes').any() 
    else group
)

这个方法就是把每个分组单独拎出来判断:如果组里有有效行,就过滤出有效行;如果全是无效行,就原封不动保留整个组,最终再把所有分组合并起来。

两种方法都能得到你想要的结果,大数据量的话更推荐第一种窗口函数的方法,性能会更好哦!

备注:内容来源于stack exchange,提问作者gernophil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 17:14:41