忽略列表顺序比较两个Pandas DataFrame并检测不匹配行
按指定规则匹配Pandas DataFrame并定位不匹配行
核心思路
要实现忽略Loc1/Loc2列内字符串顺序的等价判定,并定位不匹配行的Event编号,核心是将逗号分隔的字符串转换为集合(集合天然忽略元素顺序),再逐行比较同一Event对应的集合是否一致。
代码实现
import pandas as pd # 构造示例数据集 df1 = pd.DataFrame({ 'Event': [1, 2, 3, 4], 'Loc1': ['A, B', 'C', 'D, E', 'E, F'], 'Loc2': ['X', 'Y, Z', 'Z, Y', 'Z'] }) df2 = pd.DataFrame({ 'Event': [1, 2, 3, 4], 'Loc1': ['B, A', 'E, D', 'C', 'F, G'], 'Loc2': ['X', 'Z, Y', 'Y, Z', 'Z'] }) # 辅助函数:将逗号分隔的字符串转为去空格的集合 def str_to_set(s): return set(item.strip() for item in s.split(',')) # 对两个DF的Loc1、Loc2列批量转换为集合 df1[['Loc1_set', 'Loc2_set']] = df1[['Loc1', 'Loc2']].applymap(str_to_set) df2[['Loc1_set', 'Loc2_set']] = df2[['Loc1', 'Loc2']].applymap(str_to_set) # 按Event合并两个数据集,确保同一Event行对应比较 merged_df = pd.merge(df1, df2, on='Event', suffixes=('_df1', '_df2')) # 标记每行是否匹配(Loc1和Loc2的集合都一致才算匹配) merged_df['is_match'] = (merged_df['Loc1_set_df1'] == merged_df['Loc1_set_df2']) & \ (merged_df['Loc2_set_df1'] == merged_df['Loc2_set_df2']) # 获取不匹配的Event编号 mismatched_events = merged_df.loc[~merged_df['is_match'], 'Event'].tolist() # 输出结果 if not mismatched_events: print(pd.NA) # 完全匹配时返回NaN else: # 可选:仅返回不匹配的Event编号 print("不匹配的Event编号:", mismatched_events) # 可选:返回不匹配行的完整详情 print("\n不匹配行详情:") print(merged_df.loc[~merged_df['is_match'], ['Event', 'Loc1_df1', 'Loc2_df1', 'Loc1_df2', 'Loc2_df2']])
关键说明
str_to_set函数自动处理字符串中的空格和顺序问题,确保A, B和B, A被判定为等价- 按
Event合并数据集,避免行顺序不一致导致的错误比较 - 通过布尔索引快速筛选出不匹配的行,可灵活选择返回Event编号或完整行信息
示例运行结果
针对给定的示例数据,运行后会输出:
不匹配的Event编号: [2, 3, 4] 不匹配行详情: Event Loc1_df1 Loc2_df1 Loc1_df2 Loc2_df2 1 2 C Y, Z E, D Z, Y 2 3 D, E Z, Y C Y, Z 3 4 E, F Z F, G Z
内容的提问来源于stack exchange,提问作者psuedophyla
相关产品推荐
相关产品推荐

