使用Python核对多Excel文件中OLD与NEW数据匹配问题
解决Excel新旧工作表数据匹配核对问题(列/行顺序不同、含额外列)
你的问题核心在于DataFrame.equals()的校验规则太严格——它要求两个表的列顺序、行顺序、列数量完全一致才会返回True。针对NEW表的三个问题,我们可以通过预处理统一两个表的格式后再做校验,具体步骤如下:
处理逻辑
- 只保留两个表共有的列:丢弃NEW表中的额外列,确保列集合和OLD表一致
- 统一记录顺序:用唯一标识列(比如ID、单号这类能定位唯一记录的字段)对两个表排序;如果没有唯一标识,就按所有列排序
- 重置索引:避免原表索引不一致导致的校验失败
- 可选:统一空值格式(比如把
NaN换成空字符串),避免空值类型不同引发的误判
修改后的代码
import os import pandas as pd # 目标文件夹路径,建议用绝对路径避免问题 target_dir = "Dir" target_files = os.listdir(target_dir) for file in target_files: # 拼接正确的文件路径,避免字符串拼接的路径错误 file_path = os.path.join(target_dir, file) # 跳过非Excel文件 if not file.endswith((".xlsx", ".xls")): continue xls = pd.ExcelFile(file_path) df_old = pd.read_excel(xls, "OLD") df_new = pd.read_excel(xls, "NEW") # 1. 提取两个表的共同列,丢弃NEW表的额外列 common_cols = df_old.columns.intersection(df_new.columns) df_old_filtered = df_old[common_cols] df_new_filtered = df_new[common_cols] # 2. 按唯一标识列排序(这里假设唯一标识列是"ID",替换成你实际的列名) # 如果没有唯一标识,就用所有列排序:df_old_filtered.sort_values(by=common_cols.tolist(), inplace=True) if "ID" in common_cols: df_old_filtered.sort_values(by="ID", inplace=True) df_new_filtered.sort_values(by="ID", inplace=True) else: # 无唯一标识时按所有列排序 df_old_filtered.sort_values(by=common_cols.tolist(), inplace=True) df_new_filtered.sort_values(by=common_cols.tolist(), inplace=True) # 3. 重置索引,避免索引差异影响结果 df_old_filtered.reset_index(drop=True, inplace=True) df_new_filtered.reset_index(drop=True, inplace=True) # 4. 统一空值格式(可选,根据你的数据情况调整) df_old_filtered = df_old_filtered.fillna("") df_new_filtered = df_new_filtered.fillna("") # 5. 执行校验 is_match = df_old_filtered.equals(df_new_filtered) print(f"文件 {file} 核对结果:{'匹配' if is_match else '不匹配'}") # 可选:如果不匹配,输出具体差异 if not is_match: diff = df_old_filtered.compare(df_new_filtered) print(f"文件 {file} 差异详情:") print(diff)
额外说明
- 如果你的数据中有浮点型数值,可能存在精度问题导致误判,可以先对数值列做四舍五入处理,比如
df_old_filtered["数值列"] = df_old_filtered["数值列"].round(2) compare()函数会返回两个表的差异位置和值,方便你定位具体哪里不匹配
内容的提问来源于stack exchange,提问作者TomH
相关产品推荐
相关产品推荐

