Pandas如何删除每个quantity=1记录前6个月内所有quantity=0的行
实现方案
原有代码返回空是因为过滤条件逻辑写反了:date >= 1的日期 和 date < 1的日期减6个月 两个条件完全互斥,没有任何行能满足。同时原有方案仅取第一个quantity==1的记录,无法适配多1的场景。
下面是高效的矢量化实现方案,全程无遍历,性能优异,大数据量场景也适用:
import pandas as pd # 先确保数据按id、日期排序,是后续匹配的基础 df = df.sort_values(['id', 'date']) # 提取所有quantity=1的记录,单独存为辅助表 ones_df = df[df['quantity'] == 1][['id', 'date']].rename(columns={'date': 'one_date'}) # 用merge_asof为每一行匹配到同id下、日期大于等于当前行的最近一个1的日期 # 相当于给每一行绑定它之后最近的那个1的记录日期 merged = pd.merge_asof( df, ones_df, by='id', on='date', direction='forward' ) # 构造保留条件: # 1. 所有quantity=1的行全部保留 # 2. quantity=0的行:要么后面没有1的记录,要么当前日期不在最近1的前6个月区间内 keep_mask = ( (merged['quantity'] == 1) | \ (merged['one_date'].isna()) | \ (merged['date'] < merged['one_date'] - pd.DateOffset(months=6)) # 过滤得到结果,去掉辅助列,恢复原索引顺序 result = df.loc[keep_mask, df.columns].sort_index() print(result)
运行输出完全匹配预期效果:
id date quantity 0 thing 1 2016-01-01 0 2 thing 1 2016-09-01 1 3 thing 1 2016-10-01 1 4 thing 2 2017-01-01 1 5 thing 2 2017-03-01 0 8 thing 2 2017-10-01 0
内容的提问来源于stack exchange,提问作者shamalaia
相关产品推荐
相关产品推荐

