如何比较两个忽略列名的数据框?
Posted
技术标签:
【中文标题】如何比较两个忽略列名的数据框?【英文标题】: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])
在这种情况下,df
是 df_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 似乎都无法忽略列名。
【问题讨论】:
【参考方案1】:pd.DataFrame
是围绕pd.Series
构建的,因此您不太可能在没有列名的情况下执行比较。
但最有效的方法是下拉至numpy
:
assert_equal = (df.values == df_equal.values).all()
要处理np.nan
,可以使用np.testing.assert_equal
和catch AssertionError
,as 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()
我仍然希望看到equals
或assert_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
【讨论】:
以上是关于如何比较两个忽略列名的数据框?的主要内容,如果未能解决你的问题,请参考以下文章
如何获取和比较pyspark中两个数据框中相似列的所有值的数据类型