pandas assert_frame_equal行为

Roa*_*ord 7 python testing pandas

我试图将两个DataFrame与pandas测试进行比较assert_frame_equal.这些框架包含要与某些用户定义的精度进行比较的浮动.

check_less_precise来自的论点assert_frame_equal似乎表明我可以指定小数点后面的位数来进行比较.引用API参考页面 -

check_less_precise:指定比较精度.仅在check_exact为False时使用.比较小数点后的5位数(假)或3位数(真).如果是int,则指定要比较的数字

API参考

但是,当浮点数小于1时,这似乎不起作用.

这引发了AssertionError

import pandas as pd

expected = pd.DataFrame([{"col": 0.1}])
output = pd.DataFrame([{"col": 0.12}])
pd.testing.assert_frame_equal(expected, output, check_less_precise=1)
Run Code Online (Sandbox Code Playgroud)

虽然这不是

expected = pd.DataFrame([{"col": 1.1}])
output = pd.DataFrame([{"col": 1.12}])
pd.testing.assert_frame_equal(expected, output, check_less_precise=1)
Run Code Online (Sandbox Code Playgroud)

有人可以帮助解释这种行为,这是一个错误吗?

Ted*_*rou 8

我翻阅了源代码,发现了发生了什么。最终该函数decimal_almost_equal被调用,在普通 Python 中看起来像这样(在 Cython 中)。

def decimal_almost_equal(desired, actual, decimal):
    return abs(desired - actual) < (0.5 * 10.0 ** -decimal)
Run Code Online (Sandbox Code Playgroud)

请参阅此处的源代码这是对该函数的实际调用:

decimal_almost_equal(1, fb / fa, decimal)
Run Code Online (Sandbox Code Playgroud)

在这个例子中的什么地方

fa = .1
fb = .12
decimal = 1
Run Code Online (Sandbox Code Playgroud)

所以函数调用变成

decimal_almost_equal(1, 1.2, 1)
Run Code Online (Sandbox Code Playgroud)

其中decimal_almost_equal评估为

abs(1 - 1.2) < .5  * 10 ** -1
Run Code Online (Sandbox Code Playgroud)

或者

.2 < .05
Run Code Online (Sandbox Code Playgroud)

这是False.

所以比较是基于百分比差异而不是总差异。

如果您想要绝对比较,请查看np.allclose.

np.allclose(expected, output, atol=.1)
True
Run Code Online (Sandbox Code Playgroud)