Pandas按州分组删除最晚0值日期及之前所有观测的实现方法
解决方案
提供两种无需遍历的实现方式:
方法1:先计算全局截止日期映射再过滤
你已经算出了每个州的截止日期,只需要将截止日期匹配到每行再按规则过滤即可:
import pandas as pd # 示例数据 df = pd.DataFrame({'state':['CA']*6+['MA']*6, 'date':list(pd.date_range('2000-1-1', freq='MS', periods=6))*2, 'vals':[0, 2, 0, 4, 5, 6, 1, 2, 3, 4, 5, 6]}).set_index(['state', 'date']) # 计算每个州的截止日期 cutoff_dates = df.groupby('state').apply(lambda g: g[g['vals'] == 0].index.get_level_values(1).max()) # 匹配截止日期并过滤 df['cutoff'] = df.index.get_level_values('state').map(cutoff_dates) filtered_df = df[(df.index.get_level_values('date') > df['cutoff']) | df['cutoff'].isna()].drop('cutoff', axis=1)
方法2:直接使用groupby.apply一步完成
如果不想单独维护截止日期变量,可以直接在分组内完成过滤逻辑:
filtered_df = df.groupby('state', group_keys=False).apply( lambda g: g.loc[g.index.get_level_values('date') > g[g['vals']==0].index.get_level_values('date').max()] if (g['vals'] == 0).any() else g )
输出结果
两种方法得到的结果一致:
vals state date CA 2000-04-01 4 2000-05-01 5 2000-06-01 6 MA 2000-01-01 1 2000-02-01 2 2000-03-01 3 2000-04-01 4 2000-05-01 5 2000-06-01 6
内容的提问来源于stack exchange,提问作者Jeff
相关产品推荐
相关产品推荐

