【问题标题】:Comparing two pandas series for floating point near-equality?比较两个熊猫系列的浮点近似相等?
【发布时间】:2022-02-06 05:18:16
【问题描述】:

我可以使用pandas.Series.equals 比较两个 Pandas 系列的完全相等性。是否有相应的函数或参数来检查元素是否等于某个 ε 精度?

【问题讨论】:

  • --> np.allclose(s1, s2) 设置阈值参数,文档解释的很好。
  • @cᴏʟᴅsᴘᴇᴇᴅ,完美。将此作为答案,我会接受。
  • 并使用 np.isclose() 返回一个元素级布尔系列

标签: python pandas numpy floating-point equality


【解决方案1】:

你可以使用numpy.allclose:

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

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

公差值为正数,通常是非常小的数字。这 相对差 (rtol * abs(b)) 和绝对差 atol 加在一起以比较两者之间的绝对差异 ab

numpypandas.Series 对象配合得很好,所以如果你有两个对象 - s1s2,你可以这样做:

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

atol 是您的容差值

【讨论】:

    【解决方案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

    一种解决方法是使用一个熊猫系列的索引

    np.allclose(series_1, series_2.loc[series_1.index])
    

    【讨论】:

      【解决方案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)  
      

      引发AssertionError。所以使用check_less_precise 标志

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

      这不会引发 AssertionError,因为 check_less_precise 只比较小数点后的 3 位数字。

      See the docs here

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

      【讨论】:

        【解决方案4】:

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

        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}")
        

        【讨论】:

          猜你喜欢
          • 2016-02-11
          • 2017-08-20
          • 2013-08-29
          • 2023-03-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多