[英]Merge/Join pandas dataframe with condition
我有兩個熊貓 DataFrame df1
和df2
。 它們之間的關系是一對多的,在某些情況下可以是一對一的。 當關系是一對多時,我想加入具有某些條件的列。 我會用一些數據來說明。
import pandas as pd
df1 = pd.DataFrame({
'vid': [1, 2, 3, 4, 5],
'lid': [6, 7, 8, 9, 10],
'v': [3, 5, 6, 1, 9]
})
df2 = pd.DataFrame({
'lid': [6, 6, 8, 8, 10],
'av': ['$10','$5','$4','$3','$2'],
'cr': [0.04, 0.05, 0.03, 0.04, 0.01]
})
對於df2
中有多個連接的行,即lid
6
和8
,我想應用一些函數,比如獲取av
和cr
的max
。
預期輸出:
vid lid v av cr
1 6 3 $10 0.05
2 7 5 np.nan np.nan
3 8 6 $5 0.04
4 9 1 np.nan np.nan
5 10 9 $2 0.01
對於兩列的最大匹配或最小匹配,創建幫助列tmp
並加入通過對每個列lid
和tmp
進行排序創建的新 DataFrame ,並刪除每個lid
的重復項:
df2['tmp'] = list(zip(df2['av'].str.strip('$').astype(int), df2['cr']))
#sorting by ascending and desceding for match by maximal of tuple in col tmp
df = (df1.merge(df2.sort_values(['lid','tmp'], ascending=[True, False])
.drop_duplicates('lid'), how='left', on='lid')
.drop('tmp', axis=1))
print (df)
vid lid v av cr
0 1 6 3 $10 0.04
1 2 7 5 NaN NaN
2 3 8 6 $4 0.03
3 4 9 1 NaN NaN
4 5 10 9 $2 0.01
df2['tmp'] = list(zip(df2['av'].str.strip('$').astype(int), df2['cr']))
#sorting both ascending for match by minimal of tuple in col tmp
df = (df1.merge(df2.sort_values(['lid','tmp'])
.drop_duplicates('lid'), how='left', on='lid')
.drop('tmp', axis=1))
print (df)
vid lid v av cr
0 1 6 3 $5 0.05
1 2 7 5 NaN NaN
2 3 8 6 $3 0.04
3 4 9 1 NaN NaN
4 5 10 9 $2 0.01
編輯:如果聚合max
或mean
聚合分別為每一列工作,那么輸出與上面的解決方案不同:
df2['tmp'] = df2['av'].str.strip('$').astype(int)
df = df1.merge(df2.groupby('lid').max(), how='left', on='lid')
print (df)
vid lid v av cr tmp
0 1 6 3 $5 0.05 10.0
1 2 7 5 NaN NaN NaN
2 3 8 6 $4 0.04 4.0
3 4 9 1 NaN NaN NaN
4 5 10 9 $2 0.01 2.0
df = df1.merge(df2.groupby('lid').mean(), how='left', on='lid')
print (df)
vid lid v cr tmp
0 1 6 3 0.045 7.5
1 2 7 5 NaN NaN
2 3 8 6 0.035 3.5
3 4 9 1 NaN NaN
4 5 10 9 0.010 2.0
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.