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

基于event事件筛选多级索引Pandas DataFrame保留事件后行的方法

问题描述

现有如下 Pandas DataFrame:

import pandas as pd

df = pd.DataFrame(
    (
        {
            "foo": ["1", "1", "1", "1", "2", "2", "2", "2"],
            "bar": ["1", "2", "3", "4", "1", "2", "3", "4"],
            "info": [1, 2, 3, 4, 5, 6, 7, 8],
            "event": [0, 0, 1, 0, 0, 1, 0, 0],
        }
    )
)
# 设置多级索引
df.set_index(["foo", "bar"], inplace=True)

print(df)
# 输出:
#          info  event
# foo bar
# 1   1       1      0
#     2       2      0
#     3       3      1
#     4       4      0
# 2   1       5      0
#     2       6      1
#     3       7      0
#     4       8      0

需求:对该 DataFrame 做切片,仅保留每个按第一级索引foo分组的分组内,event等于1及之后的所有行,预期输出如下(你提到的values列对应原表的info列):

foobarinfoevent
1331
1440
2261
2370
2480

如果不需要保留event=1的行,仅保留之后的行也可接受。

解决方法

核心逻辑:对每个foo分组计算event列的累积和,从第一个event=1的位置开始,累积和将大于等于1,过滤出符合条件的行即可。

基础实现(保留event=1的行)

result = df[df.groupby(level='foo')['event'].cumsum() >= 1]
print(result)

输出和你预期的结果完全一致。

变体实现(删除event=1的行,仅保留后续行)

result = df[df.groupby(level='foo')['event'].cumsum().shift(fill_value=0) >= 1]

鲁棒性优化

如果存在部分foo分组没有event=1的记录,且你不希望保留该分组的任何行,可以使用自定义分组处理函数:

def filter_group(g):
    event_cumsum = g['event'].cumsum()
    # 分组内无event=1时返回空
    if event_cumsum.max() < 1:
        return g.iloc[0:0]
    return g[event_cumsum >= 1]

result = df.groupby(level='foo', group_keys=False).apply(filter_group)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 14:36:09