2017-03-02 30 views
2

我有兩個數據幀df1和df2。 相同的索引和相同的列名稱。 如何構建一個顯示差異的數據框,但只有至少有一個不同單元格的行? 如果行有不同的單元格,但有些相同,請保持相同的單元格不變。顯示數據幀df1,df2之間的完整行高差,但僅當行單元存在差異時

例如:

df1=pd.DataFrame({1:['a','a'],2:['c','c']}) 
df2=pd.DataFrame({1:['a','a'],2:['d','c']}) 

輸出需要:

在這個例子中
pd.DataFrame({1:['a'],2:['c->d']},index=[0]) 

輸出應該是一個行數據幀,而不是數據幀包括相同的行

NB:輸出應該含有full行在單元格中至少有一個差異

我想一個有效的解決方案,而按行迭代,並沒有在數據幀

創建特殊字符串

回答

1

您可以使用this brilliant solution

def report_diff(x): 
    return x[0] if x[0] == x[1] else '{}->{}'.format(*x) 

In [70]: pd.Panel(dict(df1=df1,df2=df2)).apply(report_diff, axis=0) 
Out[70]: 
    1  2 
0 a c->d 
1 a  c 

對於稍微複雜DataFrames:

In [73]: df1 
Out[73]: 
    A B C 
0 a c 1 
1 a c 2 
2 1 2 3 

In [74]: df2 
Out[74]: 
    A B C 
0 a d 1 
1 a c 2 
2 1 2 4 

In [75]: pd.Panel(dict(df1=df1,df2=df2)).apply(report_diff, axis=0) 
Out[75]: 
    A  B  C 
0 a c->d  1 
1 a  c  2 
2 1  2 3->4 

更新:只顯示更改/不同的行:

In [54]: mask = df1.ne(df2).any(1) 

In [55]: mask 
Out[55]: 
0  True 
1 False 
2  True 
dtype: bool 

In [56]: pd.Panel(dict(df1=df1[mask],df2=df2[mask])).apply(report_diff, axis=0) 
Out[56]: 
    A  B  C 
0 a c->d  1 
2 1  2 3->4 
+1

我喜歡它。更多pandastic – dataflow

+0

是的,我喜歡report_diff解決方案,但我想我的輸出數據框沒有相同的行。我編輯了這個問題來突出顯示它。 dataframe可以是100MB,可以包含任何字符串或數字 – alexprice

+0

@alexprice,請參閱UPDATE – MaxU

1

如何在平坦的內容老好人列表理解...

import pandas as pd 
import numpy as np 

df1=pd.DataFrame({1:['a','a'],2:['c','c']}) 
df2=pd.DataFrame({1:['a','a'],2:['d','c']}) 

rows_different_mask = (df1 != df2).any(axis=1) 

pairs = zip(df1.values.reshape(1, -1)[0], df2.values.reshape(1, -1)[0]) 
new_elems = ["%s->%s" %(old, new) if (old != new) else new for old, new in pairs] 
df3 = pd.DataFrame(np.reshape(new_elems, df1.values.shape)) 
print df3 

    0  1 
0 a c->d 
1 a  c 
相關問題