比较两个 pandas 系列的浮点近似相等?

Comparing two pandas series for floating point near-equality?

提问人:Mark Harrison 提问时间:10/4/2017 最后编辑:cs95Mark Harrison 更新时间:2/6/2022 访问量:10362

问:

我可以使用 .是否有相应的函数或参数来检查元素是否等于某些精度ε?pandas.Series.equals

python pandas numpy 浮点 相等

评论

3赞 cs95 10/4/2017
--> np.allclose(s1, s2)设置阈值参数,文档解释得很好。
1赞 Mark Harrison 10/4/2017
@c ᴏʟᴅsᴘᴇᴇᴅ,完美。把这个作为一个答案,我会接受的。
0赞 johnDanger 5/21/2020
并用于返回元素级布尔级数np.isclose()

答:

15赞 cs95 10/4/2017 #1

你可以使用 numpy.allclose

numpy.allclose(a, b, rtol=1e-05, atol=1e-08, equal_nan=False)

如果两个数组在容差范围内元素相等,则返回。True

公差值为正值,通常非常小。这 将相对差 () 和绝对差相加,以与 之间的绝对差进行比较。rtol * abs(b)atolab

numpy适用于对象,因此,如果您有两个对象 - 并且,您可以简单地执行以下操作:pandas.Seriess1s2

np.allclose(s1, s2, atol=...) 

容差值在哪里。atol

3赞 bolirev 1/2/2018 #2

Numpy 与 pandas 系列配合得很好。但是,必须注意索引的顺序(或 pandas DataFrame 的列和索引)

例如

series_1 = pd.Series(data=[0,1], index=['a','b'])
series_2 = pd.Series(data=[1,0], index=['b','a']) 
np.allclose(series_1,series_2)

将返回 False

解决方法是使用一个 pandas 系列的索引

np.allclose(series_1, series_2.loc[series_1.index])
1赞 Prakhar Pandey 4/10/2019 #3

如果你想避免numpy,还有另一种方法,使用assert_series_equal

import pandas as pd
s1 = pd.Series([1.333333, 1.666666])
s2 = pd.Series([1.333, 1.666])

from pandas.testing import assert_series_equal
assert_series_equal(s1,s2)  

引发一个 .所以使用标志AssertionErrorcheck_less_precise

assert_series_equal(s1,s2, check_less_precise= True)  # No assertion error

这不会引发 AS 仅比较小数点后的 3 位数字。AssertionErrorcheck_less_precise

请参阅此处的文档

不好使用断言,但如果你想避免numpy,这是一种方法。

评论

1赞 mikm 12/29/2022
由于自 1.1.0 起已弃用,因此现在建议改用 and。文档check_less_precisertolatol
1赞 Sterling 2/6/2022 #4

注意:我发布这个主要是因为我通过谷歌搜索类似的东西来到这个线程,它似乎太长了,无法发表评论。不一定是最佳解决方案,也不一定是严格基于“精度ε”的解决方案,但如果您想对向量(即行)而不是标量(而不是)执行此操作而不显式循环,则可以使用缩放和舍入的替代方案:DataFrameSeries

import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler

Xcomb = pd.concat((X, X2), axis=0, ignore_index=True)
# scale
scaler = MinMaxScaler()
scaler.fit(Xcomb)
Xscl = scaler.transform(Xcomb)
# round
df_scl = pd.DataFrame(np.round(Xscl, decimals=8), columns=X.columns)
# post-processing
n_uniq = df_scl.drop_duplicates().shape[0]
n_dup = df.shape[0] + df2.shape[0] - n_uniq
print(f"Number of shared rows: {n_dup}")