如何用Pandas筛选满足事件前价格均低于t=0价格的产品组?
用groupby实现需求的最优方案
针对你的需求,完全可以通过groupby高效实现,不需要额外保留新增列,下面是两种简洁的实现方式:
方法一:无额外列的分组判断
直接按id分组后,在组内完成基准价获取和前置价格的条件校验:
import pandas as pd df = pd.DataFrame({'id': [1,1,1,1,1,2,2,2,2,2], 'time': [-2,-1,0,1,2,-2,-1,0,1,2], 'price': [1,2,3,4,5,1,4,3,2,1]}) # 筛选出所有符合条件的id valid_ids = ( df.groupby('id') .apply(lambda g: g[g['time'] < 0]['price'].max() < g[g['time'] == 0]['price'].iloc[0]) .pipe(lambda s: s[s].index.tolist()) ) # 提取对应id的全量数据 result = df[df['id'].isin(valid_ids)] print(result)
方法二:结合transform的紧凑写法
如果需要临时用到基准价,用transform给每行匹配对应id的t=0价格,再做分组判断:
# 为每行添加对应id的事件时刻价格 df['event_price'] = df.groupby('id').apply( lambda g: g['price'].where(g['time'] == 0).bfill().ffill() ).reset_index(drop=True) # 筛选满足所有前置价格<基准价的id valid_ids = ( df.groupby('id') .apply(lambda g: (g[g['time'] < 0]['price'] < g['event_price']).all()) .pipe(lambda s: s[s].index.tolist()) ) # 得到结果并移除临时列 result = df[df['id'].isin(valid_ids)].drop('event_price', axis=1)
方案优势
- 逻辑连贯:利用
groupby的聚合能力,把校验和筛选整合在一起,减少中间变量 - 效率更高:针对你提到的所有产品时间窗口一致的特点,分组计算的开销更低
- 可选无额外列:第一种方法不需要修改原数据集,更轻量化
运行后输出符合预期的结果:
id time price 0 1 -2 1 1 1 -1 2 2 1 0 3 3 1 1 4 4 1 2 5
内容的提问来源于stack exchange,提问作者greyBag
相关产品推荐
相关产品推荐

