Insert/replace/merge 个数据帧到另一个数据帧的值

Insert/replace/merge values from one dataframe to another

我有两个这样的数据框:

df1 = pd.DataFrame({'ID1':['A','B','C','D','E','F'],
                    'ID2':['0','10','80','0','0','0']})
df2 = pd.DataFrame({'ID1':['A','D','E','F'],
                    'ID2':['50','30','90','50'],
                    'aa':['1','2','3','4']})

我想将df2中的ID2插入df1中的ID2,同时将aa插入df1中根据 ID1 得到一个新的 dataframe 是这样的:

df_result = pd.DataFrame({'ID1':['A','B','C','D','E','F'],
                       'ID2':['50','10','80','30','90','50'],
                         'aa':['1','NaN','NaN','2','3','4']})

我试过使用合并,但没用。

使用df.merge with Series.combine_first:

In [568]: x = df1.merge(df2, on='ID1', how='left')
In [571]: x['ID2'] = x.ID2_y.combine_first(x.ID2_x)
In [574]: x.drop(['ID2_x', 'ID2_y'], 1, inplace=True)

In [575]: x
Out[575]: 
  ID1   aa ID2
0   A    1  50
1   B  NaN  10
2   C  NaN  80
3   D    2  30
4   E    3  90
5   F    4  50

使用df.filter with df.ffill:

In [568]: x = df1.merge(df2, on='ID1', how='left')
In [597]: x['ID2'] = x.filter(like='ID2').ffill(axis=1)['ID2_y']
In [599]: x.drop(['ID2_x', 'ID2_y'], 1, inplace=True)

试试这个:

new_df = df1.assign(ID2=df1['ID2'].replace('0', np.nan)).merge(df2, on='ID1', how='left').pipe(lambda g: g.assign(ID2=g.filter(like='ID2').bfill(axis=1).iloc[:, 0]).drop(['ID2_x', 'ID2_y'], axis=1))

输出:

>>> new_df
  ID1   aa ID2
0   A    1  50
1   B  NaN  10
2   C  NaN  80
3   D    2  30
4   E    3  90
5   F    4  50

将索引设置为 ID1 后,您可以在 DataFrame 上使用 combine_first:

(df2.set_index('ID1')  # values of df2 have priority in case of overlap
    .combine_first(df1.set_index('ID1')) # add missing values from df1
    .reset_index()     # reset ID1 as column
)

输出:

  ID1 ID2   aa
0   A  50    1
1   B  10  NaN
2   C  80  NaN
3   D  30    2
4   E  90    3
5   F  50    4