繁体   English   中英

熊猫数据框相等性测试

[英]Pandas dataframes equality test

我如何编写一个函数来检查两个输入数据帧是否相等,只要两个数据帧中的行相等? 因此,它不考虑索引位置和列顺序。 我不能使用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对象

您可以sort_index索引和列值使用sort_index ,然后与eq== )或equals merge

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

您对行索引无视的要求非常困难,因为此数据类型并未针对此类操作进行优化,而对于列问题,幸运的是,这将对您有所帮助

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

我想到了,

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM