使用窗口函数筛选分组内最后statut=out的记录及紧随其后的行
Pandas 窗口函数实现分组提取目标记录
实现逻辑
核心通过name字段分区建立窗口,配合排序、排名、位移三类窗口操作完成筛选,全程不依赖逐行遍历:
- 先对数据按
name分组、组内按time升序重排,保证记录顺序和时间线一致 - 在分区窗口内对所有
statut='out'的记录按时间倒序排名,排名为1的即为分组内最后一条out记录 - 用窗口位移函数取每条记录上一行的标记,即可定位到最后一条out记录紧邻的下一行
- 筛选两类标记命中的记录即为最终结果
可运行代码
import pandas as pd import numpy as np # 构造测试样例数据 df = pd.DataFrame({ 'name': ['A','A','A','A','A','B','B','B','B'], 'time': [1,2,3,4,5,1,4,7,18], 'statut': ['in','out','in','out','in','in','in','out','in'] }) # 按分组维度+时间维度排序,保证窗口计算顺序正确 df = df.sort_values(by=['name', 'time'], ascending=[True, True]).reset_index(drop=True) # 定义分区窗口:按name分组 partition_window = df.groupby('name') # 标记组内最后一条statut=out的记录:对out记录按time倒序排名,第1名即为目标 df['out_rev_rank'] = partition_window.apply( lambda g: g.loc[g['statut'] == 'out', 'time'].rank(ascending=False, method='first') ).reset_index(level=0, drop=True) df['is_last_out'] = df['out_rev_rank'] == 1 # 标记目标out记录紧邻的下一行:窗口位移取上一行的标记值,自动隔离跨组数据 df['is_next_target'] = partition_window['is_last_out'].shift(1).fillna(False) # 筛选结果并删除辅助列 result = df[df['is_last_out'] | df['is_next_target']].drop( columns=['out_rev_rank', 'is_last_out', 'is_next_target'] ).reset_index(drop=True) print(result)
运行输出
name time statut 0 A 4 out 1 A 5 in 2 B 7 out 3 B 18 in
和预期输出完全一致。
内容的提问来源于stack exchange,提问作者Mamour
相关产品推荐
相关产品推荐

