2017-10-07 73 views
1

我有一个函数来比较两个dataframes,如果等于返回True,并False如果列名和观察是不相等的。通过他们的列名比较dataframes和意见

def table_equal(A, B): 
    var_names = sorted(A.columns) 
    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) 
    Z = B[var_names2].copy() 
    Z.sort_values(by=var_names, inplace=True) 
    Z.set_index([list(range(0,len(Y)))], inplace=True) 

    if Y.equals(Z): 
     return True 
    else: 
     return False 

比方说,我有一个原始表(A),我想比较其他表。

a b c 
x 1 hat 
y 2 cat 
z 3 bat 
w 4 rat 

我的函数适用于表B的几乎所有排列,除了下表,这是给我True而不是False为:

a c b 
x 1 hat 
y 2 cat 
z 3 bat 
w 4 rat 

有一些调整,我有做我的码?

后续问题:

我想下面的两张桌子是真正的在同一变量相同的看法。

a b c 
0 x 1 hat 
1 y 2 cat 
2 z 3 bat 
3 w 4 rat 

    c b a 
6 rat 4 w 
3 hat 1 x 
1 bat 3 z 
9 cat 2 y 

从piRSquared的解决方案,代码工作,但我怎么忽略其是在每个表完全一样的,只要意见是相同的行?

+0

对于失败的表比较,你有没有试过打印出Y'的'计算值和'Z',看看它们是什么,你认为他们应该是什么?似乎可以采取同样的基本方法来验证哪些中间步骤不按您认为的方式工作(最终导致其中一个不是您想象的)。 – martineau

+0

'Z.sort_values(by = var_names,inplace = True)'是'Z.sort_values(by = var_names2,inplace = True)'? – martineau

+0

尝试:'如果Y.reset_index(drop = True).equals(Z.reset_index(drop = True))'因为排序不会改变索引,并且通过索引完成比较。 –

回答

2

问题
很明显:

A.equals(B) 

False 

解决方案
使用pd.DataFrame.align

重写你的函数...

def table_equal(A, B): 
    X, Y = A.align(B) 
    return (X.values == Y.values).all() 

table_equal(A, B) 

False 

说明
align将返回列和索引相同的两个数据帧。

A.align(B) 

(
     a b c 
    0 x 1 hat 
    1 y 2 cat 
    2 z 3 bat 
    3 w 4 rat, 

     a b c 
    0 x hat 1 
    1 y cat 2 
    2 z bat 3 
    3 w rat 4 
) 

由于指数排列,我们可以比较values属性,看看它们都是一样的。在这种情况下,他们不是。

+0

令人惊讶的简单。谢谢 – GenXeral

+0

有没有办法忽略比较索引,只是列值['a','b','c']?例如,我不在乎表A是否具有索引0,1,2,3或6,7,8,9 – GenXeral

+0

是的,请使用'A.align(B,axis = 1)' – piRSquared