pd.util.testing.assert_frame_equal误判DataFrame列差异问题排查
排查
assert_frame_equal误判object列的常见原因 这种情况我之前踩过好几次坑——明明视觉上完全一致的列,pd.util.testing.assert_frame_equal却硬说有差异,而且其他同类型列都没问题。结合你的描述,大概率是隐藏的字符串细节差异或者容易忽略的元数据问题,给你拆解几个排查方向:
1. 肉眼不可见的字符串字符
这是最常见的原因:两个字符串看起来一模一样,但实际包含全角空格、半角空格、换行符\n、制表符\t,甚至Unicode控制字符。你可以用repr()函数打印字符串的“原始形态”,就能揪出这些隐藏字符:
# 第70列的索引是69(Python从0开始计数) print("bdf列值原始形态:", repr(bdf.iloc[0, 69])) print("cdf列值原始形态:", repr(cdf.iloc[0, 69]))
比如如果其中一个字符串末尾多了个空格,repr()会显示为'201801300040150000014217 ',一眼就能看出来。
2. 逐行定位差异行
有时候只有某几行存在差异,而你看的第一行刚好没问题。可以先找出所有不相等的行,再针对性查看:
# 比较第70列的每一行 diff_mask = bdf.iloc[:, 69] != cdf.iloc[:, 69] # 打印差异行的内容 print("bdf中差异行的列值:\n", bdf[diff_mask].iloc[:, 69]) print("cdf中差异行的列值:\n", cdf[diff_mask].iloc[:, 69])
找到差异行后再用repr()看细节,就能精准定位问题。
3. 列名的隐藏差异
虽然你说函数判定第70列有差异,但也要确认两个DataFrame的第70列列名是否真的完全一致——有时候列名会包含全角空格、不可见字符,看起来一样但实际不同,导致列对齐出错。可以用同样的repr()方法检查列名:
print("bdf第70列列名原始形态:", repr(bdf.columns[69])) print("cdf第70列列名原始形态:", repr(cdf.columns[69]))
4. 字符串编码或元数据差异
极少数情况下,两个字符串的内容和外观都一致,但编码方式不同(比如一个带UTF-8 BOM,另一个没有),或者列的其他元数据(比如flags)存在细微差别。你可以尝试统一编码后再比较:
# 统一转成UTF-8编码的字符串 bdf.iloc[:, 69] = bdf.iloc[:, 69].str.encode('utf-8').str.decode('utf-8') cdf.iloc[:, 69] = cdf.iloc[:, 69].str.encode('utf-8').str.decode('utf-8') # 再重新运行断言 pd.util.testing.assert_frame_equal(bdf, cdf, check_dtype=False, check_like=True, check_exact=True)
先从第1、2点开始排查,基本能解决90%以上的这类问题。
内容的提问来源于stack exchange,提问作者Gnowl
相关产品推荐
相关产品推荐

