如何获取pandas.testing.assert_frame_equal()检测到的全部DataFrame差异?
如何获取pandas断言DataFrame差异的所有信息?
先看测试用例:
import pandas as pd def test_two_cubes_linewise() -> None: df1 = pd.DataFrame({"A": [1, 2, 3, 4, 5.0], "B": [4, 5, 6, 7, 8.0001]}) df2 = pd.DataFrame({"A": [97, 98, 3, 4, 5], "B": [99, 5, 6, 7, 8.0002]}) pd.testing.assert_frame_equal(df1, df2, rtol=1e-3, check_dtype=False)
df1和df2的差异点:
5和5.0数据类型不同(已通过check_dtype=False忽略);1与97不相等;2与98不相等;4与99不相等;8.0001与8.0002的差异低于容差rtol=1e-3,不会被检测。
但运行测试时,pd.testing.assert_frame_equal()只会抛出第一个差异的错误信息,怎么拿到所有被检测到的差异?
两种解决方法
方法1:用pandas的verbose参数(有限显示更多差异)
从pandas 1.1.0版本开始,assert_frame_equal支持verbose参数,设置verbose=2可以显示更多差异细节,虽然不会完全列出所有差异,但比默认输出更全面:
pd.testing.assert_frame_equal(df1, df2, rtol=1e-3, check_dtype=False, verbose=2)
方法2:手动对比生成完整差异报告
如果要拿到所有差异,最可靠的方式是自己写逻辑对比两个DataFrame,提取所有超出容差的位置:
import pandas as pd import numpy as np def get_all_df_diffs(df1, df2, rtol=1e-3): # 先检查行列结构是否一致 if df1.shape != df2.shape: raise ValueError(f"DataFrame形状不匹配:{df1.shape} vs {df2.shape}") if not df1.columns.equals(df2.columns): raise ValueError(f"DataFrame列名不匹配:{list(df1.columns)} vs {list(df2.columns)}") if not df1.index.equals(df2.index): raise ValueError(f"DataFrame索引不匹配:{list(df1.index)} vs {list(df2.index)}") # 用numpy判断每个元素是否在容差范围内 is_close = np.allclose(df1.to_numpy(), df2.to_numpy(), rtol=rtol, equal_nan=True) # 转换为布尔型DataFrame标记差异位置 diff_mask = pd.DataFrame(~is_close, index=df1.index, columns=df1.columns) # 收集所有差异信息 diffs = [] for col in df1.columns: for idx in df1.index: if diff_mask.loc[idx, col]: val1 = df1.loc[idx, col] val2 = df2.loc[idx, col] # 计算相对差异 rel_diff = abs(val1 - val2) / max(abs(val1), abs(val2)) if max(abs(val1), abs(val2)) != 0 else abs(val1 - val2) diffs.append(f"位置({idx}, {col}): {val1} vs {val2},相对差异={rel_diff:.6f}") return diffs # 测试使用 df1 = pd.DataFrame({"A": [1, 2, 3, 4, 5.0], "B": [4, 5, 6, 7, 8.0001]}) df2 = pd.DataFrame({"A": [97, 98, 3, 4, 5], "B": [99, 5, 6, 7, 8.0002]}) all_diffs = get_all_df_diffs(df1, df2, rtol=1e-3) for diff in all_diffs: print(diff)
运行这段代码会输出所有超出容差的差异:
位置(0, A): 1.0 vs 97,相对差异=0.989691 位置(0, B): 4.0 vs 99,相对差异=0.959596 位置(1, A): 2.0 vs 98,相对差异=0.979592
内容的提问来源于stack exchange,提问作者Viktor
相关产品推荐
相关产品推荐

