我如何编写一个函数来检查两个输入数据帧是否相等,只要两个数据帧中的行相等?因此,它不考虑索引位置和列顺序。我不能使用df.equals(),因为它将强制数据类型相等,这不是我所需要的。
from io import StringIO
canonical_in_csv = """,c,a,b
2,hat,x,1
0,rat,y,4
3,cat,x,2
1,bat,x,2"""
with StringIO(canonical_in_csv) as fp:
df1 = pd.read_csv(fp, index_col=0)
canonical_soln_csv = """,a,b,c
0,x,1,hat
1,x,2,bat
2,x,2,cat
3,y,4,rat"""
with StringIO(canonical_soln_csv) as fp:
df2 = pd.read_csv(fp, index_col=0)
df1:
c a b
2 hat x 1
0 rat y 4
3 cat x 2
1 bat x 2
df2:
a b c
0 x 1 hat
1 x 2 bat
2 x 2 cat
3 y 4 rat
我的尝试
temp1 = (df == df2).all()
temp2 = temp1.all()
temp2
ValueError:只能比较标记相同的DataFrame对象
答案 0 :(得分:1)
您可以先按索引和列值使用sort_index
,然后将merge
与eq
(==
)或equals
一起使用:
df11 = df1.sort_index().sort_index(axis=1)
df22 = df2.sort_index().sort_index(axis=1)
print (df11.merge(df22))
a b c
0 y 4 rat
1 x 2 bat
2 x 1 hat
3 x 2 cat
print (df11.merge(df22).eq(df11))
a b c
0 True True True
1 True True True
2 True True True
3 True True True
a = df11.merge(df22).eq(df11).values.all()
#alternative
#a = df11.merge(df22).equals(df11)
print (a)
True
您的函数应重写:
def checkequality(A, B):
df11 = A.sort_index(axis=1)
df11 = df11.sort_values(df11.columns.tolist()).reset_index(drop=True)
df22 = B.sort_index(axis=1)
df22 = df22.sort_values(df22.columns.tolist()).reset_index(drop=True)
return (df11 == df22).values.all()
a = checkequality(df1, df2)
print (a)
True
答案 1 :(得分:1)
您很难要求忽略行索引,因为此数据类型并未针对此类操作进行优化,而对于列问题,幸运的是,这将对您有所帮助
df1.values == df2[df1.columns].values
其中df1.columns同步列顺序,值转换为numpy进行比较。我仍然建议不要对行进行重新排序和匹配,因为这对于较大的数据集可能会非常麻烦。 根据索引匹配,这可能就是您要寻找的
df1.values==df2.reindex(df1.index.values.tolist())[df1.columns].values
更新
@Dark指出,可以像这样进行更整洁的就地比较
df1.loc[df2.index,df2.columns] == df2
答案 2 :(得分:0)
我知道了,
def checkequality(A, B):
var_names = sorted(A.columns)
var_names
Y = A[var_names].copy()
Y.sort_values(by = var_names,inplace=True)
Y.set_index([list(range(0,len(Y)))],inplace=True)
var_names2 = sorted(B.columns)
var_names2
Y2 = B[var_names2].copy()
Y2.sort_values(by = var_names2,inplace=True)
Y2.set_index([list(range(0,len(Y2)))],inplace=True)
if (Y==Y2).all().all() == True:
return True
else:
return False