如何找出两个DataFrame间的精确匹配与非精确匹配行?
解决方案
我来给你分享一个用pandas实现需求的可行方案,步骤很直观:
1. 准备示例数据
首先我们先把你给出的两个DataFrame用代码构造出来:
import pandas as pd import numpy as np # 用于处理浮点数精度问题(可选) # 构造df1 df1 = pd.DataFrame({ 'id': [1, 2, 3, 4], 'amount': [10.00, 20.0, 90, 120.0], 'fee': [5.0, 3.0, 130.0, 35.0] }) # 构造df2 df2 = pd.DataFrame({ 'exId': [1, 2, 3, 4], 'exAmount': [10.00, 20.0, 20.0, 120.0], 'exFee': [5.0, 3.0, 3.0, 3.0] })
2. 合并两个DataFrame
我们先基于id(df1)和exId(df2)做内连接,只保留两边都存在的匹配行:
merged_df = pd.merge(df1, df2, left_on='id', right_on='exId', how='inner')
3. 筛选精确匹配的行
精确匹配要求amount与exAmount、fee与exFee都完全相等。如果是浮点数数据,建议用np.isclose代替==来避免精度误差:
# 精确匹配(浮点数安全版) exact_match = merged_df[ np.isclose(merged_df['amount'], merged_df['exAmount']) & np.isclose(merged_df['fee'], merged_df['exFee']) ] print("精确匹配") print(exact_match)
输出结果和你期望的一致:
id amount fee exId exAmount exFee 0 1 10.0 5.0 1 10.0 5.0 1 2 20.0 3.0 2 20.0 3.0
4. 筛选非精确匹配的行并标记不匹配字段
我们先筛选出id匹配但至少一个数值字段不匹配的行,然后逐行判断哪些字段不匹配并生成标记列:
# 筛选非精确匹配行 non_exact_match = merged_df[ ~np.isclose(merged_df['amount'], merged_df['exAmount']) | ~np.isclose(merged_df['fee'], merged_df['exFee']) ] # 定义函数判断不匹配字段 def get_mismatch_fields(row): mismatches = [] if not np.isclose(row['amount'], row['exAmount']): mismatches.append('amount') if not np.isclose(row['fee'], row['exFee']): mismatches.append('fee') return mismatches # 添加不匹配字段标记列 non_exact_match['mismatchFields'] = non_exact_match.apply(get_mismatch_fields, axis=1) print("\n非精确匹配") print(non_exact_match)
输出结果如下:
id amount fee exId exAmount exFee mismatchFields 2 3 90.0 130.0 3 20.0 3.0 [amount, fee] 3 4 120.0 35.0 4 120.0 3.0 [fee]
补充说明
- 如果你的数据是整数或者确定没有浮点数精度问题,也可以直接用
==和!=代替np.isclose,代码会更简洁。 - 内连接(
how='inner')确保我们只处理两边都存在的id/exId,如果需要保留某一边的所有行,可以改用left或right连接。
内容的提问来源于stack exchange,提问作者Nick01
相关产品推荐
相关产品推荐

