比较两个 pandas 系列的浮点数接近相等?
Comparing two pandas series for floating point near-equality?
我可以使用 pandas.Series.equals
比较两个 Pandas 系列是否完全相等。是否有相应的函数或参数来检查元素是否等于精度的某个ε?
您可以使用 numpy.allclose
:
numpy.allclose(a, b, rtol=1e-05, atol=1e-08, equal_nan=False)
Returns True
if two arrays are element-wise equal within a tolerance.
The tolerance values are positive, typically very small numbers. The
relative difference (rtol * abs(b)
) and the absolute difference atol
are added together to compare against the absolute difference between
a
and b
.
numpy
与 pandas.Series
对象一起使用效果很好,所以如果你有两个对象 - s1
和 s2
,你可以简单地做:
np.allclose(s1, s2, atol=...)
其中 atol
是您的 容差值 。
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)
会return假
一种解决方法是使用一个 pandas 系列的索引
np.allclose(series_1, series_2.loc[series_1.index])
如果你想避免 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)
提出 AssertionError
。所以使用 check_less_precise
标志
assert_series_equal(s1,s2, check_less_precise= True) # No assertion error
这不会引发 AssertionError
,因为 check_less_precise
只比较小数点后的 3 位数字。
不适合使用断言,但如果你想避免使用 numpy,这是一种方法。
注意:我发布这篇文章主要是因为我通过 Google 搜索类似的东西来到这个话题,而且评论似乎太长了。不一定是最好的解决方案,也不一定是严格基于“精度的 ε”,但如果您想对向量(即行)而不是 DataFrame
(而不是 [=12)的标量执行此操作,则可以使用缩放和舍入的替代方法=]) 没有显式循环:
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}")
我可以使用 pandas.Series.equals
比较两个 Pandas 系列是否完全相等。是否有相应的函数或参数来检查元素是否等于精度的某个ε?
您可以使用 numpy.allclose
:
numpy.allclose(a, b, rtol=1e-05, atol=1e-08, equal_nan=False)
Returns
True
if two arrays are element-wise equal within a tolerance.The tolerance values are positive, typically very small numbers. The relative difference (
rtol * abs(b)
) and the absolute differenceatol
are added together to compare against the absolute difference betweena
andb
.
numpy
与 pandas.Series
对象一起使用效果很好,所以如果你有两个对象 - s1
和 s2
,你可以简单地做:
np.allclose(s1, s2, atol=...)
其中 atol
是您的 容差值 。
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)
会return假
一种解决方法是使用一个 pandas 系列的索引
np.allclose(series_1, series_2.loc[series_1.index])
如果你想避免 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)
提出 AssertionError
。所以使用 check_less_precise
标志
assert_series_equal(s1,s2, check_less_precise= True) # No assertion error
这不会引发 AssertionError
,因为 check_less_precise
只比较小数点后的 3 位数字。
不适合使用断言,但如果你想避免使用 numpy,这是一种方法。
注意:我发布这篇文章主要是因为我通过 Google 搜索类似的东西来到这个话题,而且评论似乎太长了。不一定是最好的解决方案,也不一定是严格基于“精度的 ε”,但如果您想对向量(即行)而不是 DataFrame
(而不是 [=12)的标量执行此操作,则可以使用缩放和舍入的替代方法=]) 没有显式循环:
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}")