【问题标题】:How to compare two dataframes ignoring column names?如何比较两个忽略列名的数据框?
【发布时间】:2018-08-20 08:42:19
【问题描述】:

假设我想比较两个数据框的内容,而不是列名(或索引名)。 是否可以在不重命名列的情况下实现此目的?

例如:

df = pd.DataFrame({'A': [1,2], 'B':[3,4]})
df_equal = pd.DataFrame({'a': [1,2], 'b':[3,4]})
df_diff = pd.DataFrame({'A': [1,2], 'B':[3,5]})

在这种情况下,dfdf_equal 但与 df_diff 不同,因为 df_equal 中的值具有相同的内容,但 df_diff 中的值相同。请注意df_equal 中的列名不同,但我仍然想获得一个真实的值。

我尝试了以下方法:

等于:

# Returns false because of the column names
df.equals(df_equal)

当量:

# doesn't work as it compares four columns (A,B,a,b) assuming nulls for the one that doesn't exist
df.eq(df_equal).all().all()

pandas.testing.assert_frame_equal:

# same as equals
pd.testing.assert_frame_equal(df, df_equal, check_names=False)

我认为可以使用assert_frame_equal,但parameters 似乎都无法忽略列名。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    pd.DataFrame 是围绕pd.Series 构建的,因此您不太可能在没有列名的情况下执行比较。

    但最有效的方法是下拉至numpy

    assert_equal = (df.values == df_equal.values).all()
    

    要处理np.nan,可以使用np.testing.assert_equal和catch AssertionErroras suggested by @Avaris

    import numpy as np
    
    def nan_equal(a,b):
        try:
            np.testing.assert_equal(a,b)
        except AssertionError:
            return False
        return True
    
    assert_equal = nan_equal(df.values, df_equal.values)
    

    【讨论】:

      【解决方案2】:

      我只需要从数据框中获取值(numpy 数组),因此不会考虑列名。

      df.eq(df_equal.values).all().all()
      

      我仍然希望看到equalsassert_frame_equal 上的参数。也许我错过了一些东西。


      与@jpp 答案相比,这样做的一个优点是,我可以看到哪些列不匹配,只调用一次all()

      df.eq(df_diff.values).all()
      Out[24]: 
      A     True
      B    False
      dtype: bool
      

      一个问题是,当使用 eq 时,np.nan 不等于 np.nan,在这种情况下,下面的表达式会很好用:

      (df.eq(df_equal.values) | (df.isnull().values & df_equal.isnull().values)).all().all()
      

      【讨论】:

        【解决方案3】:
        df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
        df2 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
        
        for i in range(df1.shape[0]):
            for j in range(df1.shape[1]):
                print(df1.iloc[i, j] == df2.iloc[i, j])
        

        将返回:

        True
        True
        True
        True
        

        同样的事情:

        df1 = pd.DataFrame({'a': [1, 2], 'b': [3, 4]})
        df2 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
        

        一个明显的问题是,列名在 Pandas 中对数据帧进行排序很重要。例如:

        df1 = pd.DataFrame({'a': [1, 2], 'b': [3, 4]})
        df2 = pd.DataFrame({'a': [1, 2], 'B': [3, 4]})
        print(df1)
        print(df2)
        

        呈现为('B' 在 df2 中的 'a' 之前):

           a  b
        0  1  3
        1  2  4
           B  a
        0  3  1
        1  4  2
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-07-30
          • 1970-01-01
          • 1970-01-01
          • 2021-02-18
          • 2021-01-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多