用pandas.read_excel读取前需先用ExcelFile查看sheet名并显式指定sheet_name和header;比对时用merge+indicator标记来源,关键列要统一类型、去空格、处理空值;数值用isclose容差比较,文本需标准化;导出差异时记录原始位置信息。

用 pandas.read_excel 读取表格前先确认 sheet 名和数据结构
直接读 Excel 容易因默认 sheet_name=0 读错工作表,或忽略空行/标题行偏移。实际中两个文件的表头可能不完全一致(比如“订单号” vs “OrderID”),甚至列顺序不同——这时不能靠列位置比对,得靠列名对齐。
实操建议:
- 先用
pandas.ExcelFile查看所有 sheet:xl = pd.ExcelFile("a.xlsx")<br>print(xl.sheet_names) - 读取时显式指定
sheet_name和header(例如header=1表示第二行为列名) - 读入后立刻检查
df.columns.tolist()和df.shape,确认行列数、列名是否预期一致
用 merge + indicator=True 找出差异行
这是最稳的比对方式:把两个 DataFrame 按关键列(如 ID 或组合主键)合并,用 _merge 列标记来源(both/left_only/right_only),比手写循环或 compare() 更可控、更易调试。
常见错误现象:合并后结果为空,或差异行数量远超预期——大概率是关键列存在空值、类型不一致(比如一列为 int64,另一列为 object 含字符串"null")或前后空格未清理。
立即学习“Python免费学习笔记(深入)”;
实操建议:
- 合并前统一处理关键列:
df["id"] = df["id"].astype(str).str.strip() - 用
how="outer"确保两边独有行都不丢失 - 示例:
diff = pd.merge(df1, df2, on=["id", "name"], how="outer", indicator=True)<br>only_in_a = diff[diff["_merge"] == "left_only"]<br>only_in_b = diff[diff["_merge"] == "right_only"]
数值或文本字段需单独处理精度与空值
Excel 中的数字常被读成 float,但原始值可能是整数;文本字段可能含不可见字符(\xa0、\t)或大小写混用。直接用 == 比较会漏掉这些“看似相同实则不同”的行。
实操建议:
- 数值列比对前先转为相同类型并设容差:
np.isclose(df1["price"], df2["price"], atol=1e-6) - 文本列统一小写 + 去首尾空格 + 替换常见空白符:
df["desc"].str.lower().str.strip().str.replace(r"[\s\u00A0]+", " ", regex=True) - 空值(
NaN)在 merge 或 == 中默认不相等,要用pandas.isna()单独判断是否“两边都是空”
导出差异结果时保留原始格式和定位信息
只导出差异数据不够——业务方常需要知道某行在原 Excel 的第几行、哪个 sheet、甚至带原单元格背景色。pandas 本身不存这些信息,所以必须在读取阶段就记录位置。
实操建议:
- 读取时加
keep_default_na=False防止把空字符串误转为NaN - 用
pd.read_excel(..., skiprows=0, nrows=1000)控制范围,并用df.index记录逻辑行号(注意跳过 header 后需 +1 或 +2) - 导出差异结果时,额外加两列:
source_file和excel_row,方便回溯 - 若需高亮样式,用
openpyxl写回 Excel,而不是仅用to_excel
merge 出来的“差异”可能全是噪音。


















