基于ID和STATUS合并DataFrame时匹配含NULL值行的实现问题
问题解决:DataFrame按条件匹配合并
问题描述
需要合并两个DataFrame,匹配规则如下:
- 当df2中某行的STATUS为空值时,仅按ID匹配获取对应BRANCH
- 当df2中STATUS有有效值时,需同时按ID和STATUS两列匹配
当前使用的合并代码无法满足需求:
mer_col_list = ['ID','STATUS'] df_out = pd.merge(df1,df2, on=mer_col_list, how='left')
数据示例
df1数据:
| ID | STATUS | NAME |
|---|---|---|
| 11 | ACTIVE | John |
| 22 | DORMANT | NICK |
| 33 | NOT_ACTIVE | HARRY |
df2数据:
| ID | STATUS | BRANCH |
|---|---|---|
| 11 | DORMANT | USA |
| 11 | USA | |
| 22 | UK | |
| 33 | NOT_ACTIVE | AUS |
期望结果
| ID | NAME | BRANCH |
|---|---|---|
| 11 | John | USA |
| 22 | NICK | UK |
| 33 | HARRY | AUS |
解决方案
通过两步匹配+填充的方式实现需求,具体代码如下:
import pandas as pd # 模拟输入数据 df1 = pd.DataFrame({ 'ID': [11, 22, 33], 'STATUS': ['ACTIVE', 'DORMANT', 'NOT_ACTIVE'], 'NAME': ['John', 'NICK', 'HARRY'] }) df2 = pd.DataFrame({ 'ID': [11, 11, 22, 33], 'STATUS': ['DORMANT', pd.NA, pd.NA, 'NOT_ACTIVE'], 'BRANCH': ['USA', 'USA', 'UK', 'AUS'] }) # 第一步:按ID+STATUS执行左连接,匹配STATUS有值的情况 df_merge = pd.merge(df1, df2, on=['ID', 'STATUS'], how='left') # 提取df2中STATUS为空的行,仅保留ID和BRANCH并去重,用于后续填充 df2_null_status = df2[df2['STATUS'].isna()][['ID', 'BRANCH']].drop_duplicates() # 第二步:对第一步未匹配到BRANCH的行,按ID匹配填充 df_out = df_merge.merge(df2_null_status, on='ID', how='left', suffixes=('', '_fill')) df_out['BRANCH'] = df_out['BRANCH'].fillna(df_out['BRANCH_fill']) # 整理并输出最终结果 df_out = df_out[['ID', 'NAME', 'BRANCH']] print(df_out)
代码说明
- 优先执行ID+STATUS的左连接,直接匹配df2中STATUS有有效值的行(如ID=33的记录)
- 预处理df2中STATUS为空的行,避免同一ID对应多个重复的BRANCH值
- 对第一步未匹配到BRANCH的行,用仅按ID匹配的结果填充(如ID=11、ID=22的记录)
- 最后整理列,得到符合要求的输出结果
内容的提问来源于stack exchange,提问作者DEs
相关产品推荐
相关产品推荐

