如何比较忽略列名的两个数据帧?

时间:2018-03-12 10:49:25

标签: python pandas dataframe

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

例如:

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似乎都无法忽略列名。

3 个答案:

答案 0 :(得分:1)

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

但最有效的方法是下降到pd.Series

numpy

要处理assert_equal = (df.values == df_equal.values).all() ,您可以使用np.nan并抓住np.testing.assert_equalas suggested by @Avaris

AssertionError

答案 1 :(得分:0)

我只需要从数据框中获取值(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()

答案 2 :(得分:0)

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