如何比对两个Pandas DataFrame,筛选指定列可差异的半匹配行
实现方案
核心逻辑是把不允许值不同的列作为merge的关联键,直接用pandas的merge方法即可,不受两个表的行顺序影响。
通用实现代码
import pandas as pd def semi_match_merge(df1, df2, ignore_cols: list): """ 半匹配合并两个DataFrame :param df1: 第一个待匹配的DataFrame :param df2: 第二个待匹配的DataFrame :param ignore_cols: 允许值不同的列名列表,其余列必须全部相等才会匹配 :return: 匹配后的结果 """ # 取两个表的公共列,排除允许忽略的列作为关联键 common_cols = list(set(df1.columns) & set(df2.columns)) merge_on = [col for col in common_cols if col not in ignore_cols] # 执行内连接,只保留两边都匹配上的行 matched = pd.merge(df1, df2, on=merge_on, how='inner', suffixes=('_df1', '_df2')) return matched
使用示例
针对你提供的测试数据,要允许Relationship列值不同,其余两列必须相等,调用方式如下:
# 测试数据 d1 = {'Entity1': ['x1', 'x2','x3','x4','x1', 'x6', 'x1'], 'Relationship': ['y1', 'y2','y3','y4','y5','y6', 'y9'], 'Entity2': ['z1', 'z2','z3','z4','z5','z6', 'z5']} df1 = pd.DataFrame(data=d1) d2 = {'Entity1': ['x3', 'x4','x1','x2','x6','x1'], 'Relationship': ['y3', 'y4','y1','y2','y6','y7'], 'Entity2': ['z3', 'z4','z1','z2','z7','z5']} df2 = pd.DataFrame(data=d2) # 调用半匹配方法,允许Relationship列不同 result = semi_match_merge(df1, df2, ignore_cols=['Relationship']) print(result)
结果说明
返回结果会包含所有符合要求的匹配条目:
- 完全匹配的条目:比如
Entity1=x2, Entity2=z2对应的两行,Relationship值都为y2 - 半匹配的条目:比如
Entity1=x1, Entity2=z5对应的两行,df1的Relationship为y5,df2的Relationship为y7
如果只需要保留唯一的行组合,可以在返回结果后加.drop_duplicates()去重。
内容的提问来源于stack exchange,提问作者Penguin
相关产品推荐
相关产品推荐

