2016-11-29 68 views
0

一個數據幀的更新列我有一個問題,我找到了一個解決辦法,但我覺得這是錯誤的方式來做到這一點。也許,有一個更「規範」的方式來做到這一點。熊貓(蟒蛇) - 從另一個與條件和不同的列

我已經had an answer for a really similar problem,但在這裏我沒有在每個數據幀行的量相同。對不起,「雙後」,但第一個仍然有效,所以我認爲最好是做一個新的。

問題

我有兩個數據框,我想,而無需額外的列,但不刪除現有的相關信息進行合併。例如:

現有數據幀(DF)

A A2 B 
0 1 4 0 
1 2 5 1 
2 2 5 1 

數據幀合併(DF2)

A A2 B 
0 1 4 2 
1 3 5 2 

我想與df2更新df如果列 'A' 和 'A2' 對應。 其結果將是:

A A2 B 
0 1 4 2 <= Update value ONLY 
1 2 5 1 
2 2 5 1 

這裏是我的解決方案,但我認爲這不是一個非常好的一個。

import pandas as pd 

df = pd.DataFrame([[1,4,0],[2,5,1],[2,5,1]],columns=['A','A2','B']) 

df2 = pd.DataFrame([[1,4,2],[3,5,2]],columns=['A','A2','B']) 

df = df.merge(df2,on=['A', 'A2'],how='left') 
df['B_y'].fillna(0, inplace=True) 
df['B'] = df['B_x']+df['B_y'] 
df = df.drop(['B_x','B_y'], axis=1) 
print(df) 

我試過這個解決方案:

rows = (df[['A','A2']] == df2[['A','A2']]).all(axis=1) 
df.loc[rows,'B'] = df2.loc[rows,'B'] 

但我因爲錯誤的行數的這個錯誤:

ValueError: Can only compare identically-labeled DataFrame objects 

有沒有人有一個更好的辦法呢? 謝謝!

回答

1

我認爲你可以使用DataFrame.isin進行檢查,其中在兩種DataFrames同一行。然後通過mask創建NaN,其由combine_first填充。最後投給int

mask = df[['A', 'A2']].isin(df2[['A', 'A2']]).all(1) 
print (mask) 
0  True 
1 False 
2 False 
dtype: bool 

df.B = df.B.mask(mask).combine_first(df2.B).astype(int) 
print (df) 
    A A2 B 
0 1 4 2 
1 2 5 1 
2 2 5 1 
+0

謝謝!不是那麼容易,但我會分析/學習/使用這個:D – Lerenn

1

隨着在布爾面具被創建的方式細微調整,就可以得到它的工作:

cols = ['A', 'A2'] 
# Slice it to match the shape of the other dataframe to compare elementwise 
rows = (df[cols].values[:df2.shape[0]] == df2[cols].values).all(1) 
df.loc[rows,'B'] = df2.loc[rows,'B'] 
df 

enter image description here