Pandas DataFrame如何优雅删除连续SWITCH行仅保留块末行及所有RESULT行
解决方案
原有实现出错的核心原因是遍历DataFrame的同时直接删除行,会导致遍历索引和实际数据的行对应关系错乱,同时iterrows遍历的方式性能很低,不适合处理中大规模数据。
以下是两种高效、符合Pythonic规范的实现方案:
实现1:极简布尔索引(推荐,性能最优)
直接通过向量运算构造过滤条件,无需循环和分组,性能比逐行遍历高1~2个数量级:
import pandas as pd data = {'TYPE':['SWITCH','SWITCH','SWITCH', 'SWITCH','RESULT','RESULT','RESULT', 'RESULT','RESULT','SWITCH','SWITCH', 'RESULT','RESULT','RESULT','RESULT'], 'RESULT':['YES', 'NO','NO','YES', 'DONE','DONE','DONE', 'DONE','DONE','NO', 'YES','DONE','DONE', 'DONE','DONE']} df = pd.DataFrame(data) # 构造过滤条件 # 条件1:所有RESULT类型行全部保留 cond_result = df['TYPE'] == 'RESULT' # 条件2:SWITCH类型行,且是连续SWITCH块的最后一行(下一行不是SWITCH) cond_switch_last = (df['TYPE'] == 'SWITCH') & (df['TYPE'].shift(-1) != 'SWITCH') # 按条件过滤 df_filtered = df[cond_result | cond_switch_last] print(df_filtered)
输出完全匹配预期:
TYPE RESULT 3 SWITCH YES 4 RESULT DONE 5 RESULT DONE 6 RESULT DONE 7 RESULT DONE 8 RESULT DONE 10 SWITCH YES 11 RESULT DONE 12 RESULT DONE 13 RESULT DONE 14 RESULT DONE
实现2:分组筛选(逻辑更直观,适合复杂规则扩展)
如果后续过滤规则需要调整扩展,可以用连续分组的方式处理,逻辑可读性更强:
# 生成连续同类型的分组ID,相邻TYPE不同时分组ID+1 df['group_id'] = (df['TYPE'] != df['TYPE'].shift()).cumsum() def group_filter(g): # RESULT组全保留,SWITCH组仅保留最后一行 return g if g['TYPE'].iloc[0] == 'RESULT' else g.tail(1) df_filtered = df.groupby('group_id', group_keys=False).apply(group_filter).drop(columns='group_id')
内容的提问来源于stack exchange,提问作者Ginger_Chacha
相关产品推荐
相关产品推荐

