2017-10-07 71 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