基于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列):
| foo | bar | info | event |
|---|---|---|---|
| 1 | 3 | 3 | 1 |
| 1 | 4 | 4 | 0 |
| 2 | 2 | 6 | 1 |
| 2 | 3 | 7 | 0 |
| 2 | 4 | 8 | 0 |
如果不需要保留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
相关产品推荐
相关产品推荐

