2017-02-15 90 views
0

我有兩個數據幀包含(一些)公共列(A,B,C),但排序不同,並且C的值不同。基於兩個熊貓數據幀之間的多個條件進行選擇創建一個新列

我想用第二個數據框中的'C'值替換第一個數據框中的'C'值。

我可以這樣創造的玩具例子:

A = [ 1, 1, 1, 2, 2, 2, 3, 3, 3 ] 
B = [ 'x', 'y', 'z', 'x', 'y', 'y', 'x', 'x', 'x' ] 
C = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i' ] 

df1 = pd.DataFrame({ 'A' : A, 
         'B' : B, 
         'C' : C }) 

A.reverse() 
B.reverse() 
C = [ c.upper() for c in reversed(C) ] 

df2 = pd.DataFrame({ 'A' : A, 
         'B' : B, 
         'C' : C }) 

我想,這樣它看起來像這樣更新DF1 - 即它從DF2的「C」值:

A = [ 1, 1, 1, 2, 2, 2, 3, 3, 3 ] 
B = [ 'x', 'y', 'z', 'x', 'y', 'y', 'x', 'x', 'x' ] 
C = [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I' ] 

我已經試過:

df1['C'] = df2[ (df2['A'] == df1['A']) & (df2['B'] == df1['B']) ]['C'] 

但是,這並不工作,因爲,我認爲,A和B的順序是不同的。

回答

2
merge_df = pd.merge(df1, df2, on=['A', 'B']) 
df1['C'] = merge_df['C_y'] 

我覺得你的玩具代碼具有用於C. C()在[c.upper問題reverse()]。 C.reverse()返回無。

0

這並不容易,因爲AB3,x)列中的重複項。 所以我創建新列D通過cumcount然後用 merge,最後刪除不必要的列:

df1['D'] = df1.groupby(['A','B']).C.cumcount() 
df2['D'] = df2.groupby(['A','B']).C.cumcount(ascending=False) 

df3 = pd.merge(df1, df2, on=['A','B','D'], how='right', suffixes=('_','')) 
df3 = df3.drop(['C_', 'D'], axis=1) 
print (df3) 
    A B C 
0 1 x A 
1 1 y B 
2 1 z C 
3 2 x D 
4 2 y E 
5 2 y F 
6 3 x G 
7 3 x H 
8 3 x I 
相關問題