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

基于多条件分组过滤DataFrame:满足条件后移除后续行

问题解决:按ID截断Payment Done成功后的后续行

问题背景

原始DataFrame:

ID       Activity     Action No.    Status  
A1       register         1           in
A1       fill form        2           in
A2       Payment Done     3         success
A2       fill form        2           in
B1       fill form        1           in
B1       Payment Done     2         success
B1       Process_drop     3           in
B1       fill form        1           in

预期得到的DataFrame:

ID       Activity     Action No.    Status  
A1       register         1           in
A1       fill form        2           in
A2       Payment Done     3         success
B1       Payment Done     2         success

需求:对每个ID,一旦出现Activity == 'Payment Done'且Status == 'success'的行,就删除该ID在这行之后的所有记录。

解决方案

用Pandas的分组和累积判断就能实现,直接看步骤和代码:

实现步骤

  1. 给每行打标记,判断是否是触发截断的目标行;
  2. 按ID分组,用累积最大值(cummax())追踪是否已经出现过触发行——只要出现过一次,后续所有行的标记都会变成True;
  3. 筛选出触发行及之前的所有记录,最后清理辅助列。

完整代码

import pandas as pd

# 构造原始数据(如果已有现成DataFrame,可跳过此步骤)
data = {
    'ID': ['A1', 'A1', 'A2', 'A2', 'B1', 'B1', 'B1', 'B1'],
    'Activity': ['register', 'fill form', 'Payment Done', 'fill form', 'fill form', 'Payment Done', 'Process_drop', 'fill form'],
    'Action No.': [1, 2, 3, 2, 1, 2, 3, 1],
    'Status': ['in', 'in', 'success', 'in', 'in', 'success', 'in', 'in']
}
df = pd.DataFrame(data)

# 标记触发截断的行
df['trigger'] = (df['Activity'] == 'Payment Done') & (df['Status'] == 'success')
# 按ID计算:保留触发行及之前的所有记录
df['keep'] = df.groupby('ID')['trigger'].transform(lambda x: ~x.cummax() | x)
# 筛选结果并删除辅助列
result_df = df[df['keep']].drop(columns=['trigger', 'keep'])

print(result_df)

代码解释

  • cummax()在分组内从前往后遍历,只要碰到一次True(触发行),后面所有行的这个值都会保持True,相当于标记“已经过了截断点”;
  • ~x.cummax()保留截断点之前的行,|x把触发行本身也包含进来,刚好得到我们需要的结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 02:40:38