Python Excel两表对比找出差异
用pandas对比两个Excel文件,找出A表有B表没有的行、B表有A表没有的行、以及同一条记录数值不一致的行,输出差异报告。
场景痛点
两份客户名单、两个月的工资表、版本不同的合同台账,要找出"哪些是新增、哪些被删除、哪些字段改了"。Excel里用Vlookup+IF一层层套,公式长到自己都看不懂。Python用merge一次对齐,差异一目了然。
用到的库
pip install pandas openpyxl
完整代码
import pandas as pd
def compare_two_excel(file_a, file_b, key_col, output_file):
"""
按主键列对比两个Excel
key_col: 用来对齐的唯一键,比如"订单号""手机号"
"""
df_a = pd.read_excel(file_a)
df_b = pd.read_excel(file_b)
# 标记来源
df_a["来源"] = "A表"
df_b["来源"] = "B表"
# 外连接,indicator列标记每行来自哪边
merged = df_a.merge(df_b, on=key_col, how="outer", suffixes=("_A", "_B"), indicator=True)
# 1. 只在A表
only_a = merged[merged["_merge"] == "left_only"]
# 2. 只在B表
only_b = merged[merged["_merge"] == "right_only"]
# 3. 两边都有,逐列比较
both = merged[merged["_merge"] == "both"].copy()
# 找出两边都存在但内容不同的行
diff_rows = []
common_cols = [c for c in df_a.columns if c != key_col and c != "来源"]
for col in common_cols:
col_a = col + "_A" if col + "_A" in both.columns else col
col_b = col + "_B" if col + "_B" in both.columns else col
if col_a in both.columns and col_b in both.columns:
both[col + "_不同"] = both[col_a] != both[col_b]
# 保存结果
with pd.ExcelWriter(output_file, engine="openpyxl") as writer:
only_a.to_excel(writer, sheet_name="只在A表", index=False)
only_b.to_excel(writer, sheet_name="只在B表", index=False)
both.to_excel(writer, sheet_name="两边都有对比", index=False)
print(f"只在A表: {len(only_a)}行")
print(f"只在B表: {len(only_b)}行")
print(f"两边都有: {len(both)}行")
print(f"对比结果已保存: {output_file}")
if __name__ == "__main__":
compare_two_excel(
"./表A_上月.xlsx",
"./表B_本月.xlsx",
key_col="订单号",
output_file="./差异报告.xlsx"
)
代码讲解
merge(..., how="outer", indicator=True)外连接,_merge列会标记left_only/right_only/both,一次分出三类。suffixes=("_A","_B")让同名列区分来源,避免被自动改后缀后搞混。- 对两边都有的记录,逐列比较
!=,生成xxx_不同布尔列,直接看出哪列变了。 - 三个结果分别写到不同sheet,业务方打开就能看。
运行结果
生成 差异报告.xlsx,三个sheet:"只在A表"(新增/丢失)、"只在B表"(新增/丢失)、"两边都有对比"(含每列是否变化的标记列)。
注意事项
- 主键列必须唯一,否则merge会产生笛卡尔积;先用
df[key].duplicated().sum()检查。 - 浮点数值直接
!=会因精度报错差异,建议round(2)后再比。 - 日期格式两表不一致时,先统一
pd.to_datetime再对比。

更新时间:2026-09-15 09:19:05
下一篇: