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

Python pandas如何按多条件删除分组DataFrame中满足规则的指定行

问题背景

现有按id字段分组的DataFrame如下:

id outcome
0    3      no
1    3      no
2    3      no
3    3     yes
4    3      no
5    5      no
6    5      no
7    5     yes
8    5     yes
9    6      no
10   6      no
11   6     yes
12   6     yes
13   6     yes
14   6     yes
15   6     yes
16   6      no
17   6      no
18   6      no
19   7      no
20   7      no
21   7     yes
22   7     yes
23   7      no
24   7      no
25   7      no
26   7      yes

需要按照以下规则完成行删除:

  • 若当前行的下一行outcome取值与当前行一致,删除当前行
  • 若某行outcome为yes,其后一行必须是序列中第一个出现的no
  • 连续yes序列中仅保留最后一个yes行
  • 保留yes序列上方最后一个no,连续no序列中保留第一个和最后一个no
  • 删除每个id分组最后一行为yes的行
  • 处理完成后若某个id仅剩下1行no记录,删除该id对应的所有行

预期输出

id outcome
2    3      no
3    3     yes
4    3      no
10   6      no
15   6     yes
16   6      no
20   7      no
22   7     yes
23   7      no
25   7      no
26   7      yes

现有问题

当前实现第一部分保留了连续yes序列的第一个行而非要求的最后一个,同时第2、3部分的写法较为冗余,需要更精简的方案一次性满足所有条件。

解决方案

通过分组内打连续块标签的方式一次性处理所有过滤规则,代码如下:

import pandas as pd

# 构造原始DataFrame
df = pd.DataFrame({
    'id': [3,3,3,3,3,5,5,5,5,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7],
    'outcome': ['no','no','no','yes','no','no','no','yes','yes','no','no','yes','yes','yes','yes','yes','no','no','no','no','no','yes','yes','no','no','no','yes']
})

def filter_id_group(g):
    # 为连续相同的outcome序列打块标签
    g['block'] = (g['outcome'] != g['outcome'].shift()).cumsum()
    # 按块过滤:no块保留首尾行,yes块仅保留最后一行
    filtered = g.groupby('block', group_keys=False).apply(
        lambda x: x.iloc[[0, -1]] if x['outcome'].iloc[0] == 'no' else x.iloc[[-1]]
    ).drop_duplicates() # 处理长度为1的块时避免重复保留同一行
    # 删除分组最后一行为yes的行
    if filtered.iloc[-1]['outcome'] == 'yes':
        filtered = filtered.iloc[:-1]
    # 剩余行数<=1时直接返回空表删除整个分组
    if len(filtered) <= 1:
        return pd.DataFrame(columns=filtered.columns)
    return filtered.drop('block', axis=1)

# 按id分组处理后重置索引
result = df.groupby('id', group_keys=False).apply(filter_id_group).reset_index(drop=True)
print(result)

代码逻辑完全匹配所有规则,不需要多阶段拼接过滤条件,可读性和维护性更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 02:15:01