如何用pandas、numpy对比行列数不一致的多工作表Excel工作簿
原代码失效原因
- 核心报错点在
df1.values == df2sheet.values语句:numpy逐元素比较要求两个数组形状完全一致,只要两个同名工作表行数或列数不相等,就会直接抛出维度不匹配错误,后续差异标记逻辑完全无法执行。 - 原逻辑仅遍历第一个文件内的工作表,会遗漏第二个文件独有的工作表。
- 循环变量命名和初始读取的文件1字典重名,存在变量覆盖隐患。
- 没有处理行列不对齐时单边多出的行、列内容,即使不报错也会截断差异内容。
- 未做空值兼容:两个单元格同时为空值时,
==判断会返回False,产生误报。
修正后可兼容行列不一致场景的代码
import pandas as pd import numpy as np # 读取两个文件的所有工作表,返回格式为{工作表名: 对应DataFrame} book1 = pd.read_excel('test_1.xlsx', sheet_name=None) book2 = pd.read_excel('test_2.xlsx', sheet_name=None) # 收集两个文件中出现过的所有工作表名,避免遗漏单边独有表 all_sheets = set(book1.keys()).union(set(book2.keys())) with pd.ExcelWriter('./Excel_diff.xlsx') as writer: for sheet_name in all_sheets: # 处理工作表仅在文件1存在的情况 if sheet_name not in book2: res_df = book1[sheet_name].applymap(lambda x: f'{x} → [文件2无此工作表]') res_df.to_excel(writer, sheet_name=sheet_name, index=False) continue # 处理工作表仅在文件2存在的情况 if sheet_name not in book1: res_df = book2[sheet_name].applymap(lambda x: f'[文件1无此工作表] → {x}') res_df.to_excel(writer, sheet_name=sheet_name, index=False) continue df1_sheet = book1[sheet_name] df2_sheet = book2[sheet_name] # 外连接对齐两个表的行、列,缺失位置填充统一标记,解决维度不匹配问题 df1_aligned, df2_aligned = df1_sheet.align( df2_sheet, join='outer', fill_value='[无对应单元格]' ) # 生成比较掩码:值完全相等、或两边均为空值时判定为内容一致 compare_mask = (df1_aligned == df2_aligned) | (df1_aligned.isna() & df2_aligned.isna()) # 定位所有差异单元格,替换为「文件1值 → 文件2值」的格式 diff_rows, diff_cols = np.where(~compare_mask) for row, col in zip(diff_rows, diff_cols): val1 = df1_aligned.iloc[row, col] val2 = df2_aligned.iloc[row, col] df1_aligned.iloc[row, col] = f'{val1} → {val2}' # 写入差异结果 df1_aligned.to_excel(writer, sheet_name=sheet_name, index=False, header=True)
代码逻辑说明
- 自动覆盖所有工作表:不管工作表是两个文件共有、还是仅在单个文件存在,都会被写入最终差异结果文件。
- 行列自动对齐:同名表对比前会自动补全两边缺失的行、列,不会因为行列数不一致报错,也不会截断任何一边的内容。
- 空值判断优化:两个单元格同时为空时不会误判为差异。
- 差异标记清晰:单元格内容不一致、单元格仅在单边存在、工作表仅在单边存在三类场景都有明确的标记文本,可直接定位差异。
内容的提问来源于stack exchange,提问作者T P Alexander
相关产品推荐
相关产品推荐

