Pandas实现:按两列GUID去重DataFrame并保留唯一订单及对应列
Pandas DataFrame 无循环过滤实现方案
明确过滤规则
- 规则1:
event_out/event_in中的GUID只要被任意订单使用过,所有包含该GUID的其他行必须删除 - 规则2:若某订单的某一行被保留,该订单的其余行全部忽略
- 规则3:最终结果中,
event_out的GUID不能出现在event_in列,event_in的GUID也不能出现在event_out列
无循环实现代码
假设原数据集为df,包含order_id、event_out、event_in及其他业务列。以下方案通过Pandas矢量化操作完成所有规则过滤:
import pandas as pd # 第一步:处理规则3,先过滤掉违反GUID互斥的行 in_guids = set(df['event_in'].dropna()) out_guids = set(df['event_out'].dropna()) step1 = df[~df['event_out'].isin(in_guids) & ~df['event_in'].isin(out_guids)] # 第二步:处理规则2,每个订单仅保留第一行 step2 = step1.drop_duplicates(subset='order_id', keep='first') # 第三步:处理规则1,确保每个GUID仅出现一次 # 标记重复的GUID行 step2['out_dup'] = step2['event_out'].duplicated(keep='first') step2['in_dup'] = step2['event_in'].duplicated(keep='first') # 过滤掉重复GUID的行,得到最终结果 final_df = step2[~step2['out_dup'] & ~step2['in_dup']].drop(columns=['out_dup', 'in_dup'])
方案说明
- 规则3通过集合匹配快速过滤互斥违规行,利用Pandas的
isin矢量化操作,比循环判断效率高得多 - 规则2直接用
drop_duplicates按订单去重并保留首行,省去循环里的订单跟踪逻辑 - 规则1通过
duplicated标记重复GUID的行,仅保留首次出现的行,确保每个GUID只被一个订单使用
循环实现示例(参考)
这是你可能用到的循环版本,供对比参考:
import pandas as pd used_guids = set() kept_orders = set() result_rows = [] # 提取规则3的互斥集合 in_guids = set(df['event_in'].dropna()) out_guids = set(df['event_out'].dropna()) for idx, row in df.iterrows(): # 跳过已保留过的订单 if row['order_id'] in kept_orders: continue # 跳过已使用过的GUID或违反规则3的行 if row['event_out'] in used_guids or row['event_in'] in used_guids: continue if row['event_out'] in in_guids or row['event_in'] in out_guids: continue # 保留该行并更新标记集合 result_rows.append(row) kept_orders.add(row['order_id']) used_guids.add(row['event_out']) used_guids.add(row['event_in']) final_df_loop = pd.DataFrame(result_rows)
内容的提问来源于stack exchange,提问作者Alexander Survillo
相关产品推荐
相关产品推荐

