Pandas合并DataFrame时填充NaN值的实现方案
Pandas合并DataFrame:填充NaN并合并重复列
问题背景
现有两个DataFrame:
people表
| id | skills | diploma |
|---|---|---|
| 1 | nan | omicron |
| 2 | beta | nan |
| 5 | beta | epsilon |
| 6 | omega | zeta |
jobs表
| id | people_id | skills | diploma |
|---|---|---|---|
| 10 | 1 | alpha | nan |
| 20 | 2 | nan | zeta |
| 30 | 3 | beta | pi |
| 40 | 4 | omega | zeta |
执行pd.merge(people, jobs, left_on='id', right_on='people_id', how='inner')后,结果存在重复列与NaN值。需要实现:
- 合并后用两个表的信息填充NaN值
- 保留job的id
- 将重复的skills和diploma列合并为单一列
- 最终每行对应一个job,仅保留
id(job的id)、people_id、skills、diploma列,期望结果如下:
| id | people_id | skills | diploma |
|---|---|---|---|
| 10 | 1 | alpha | omicron |
| 20 | 2 | beta | zeta |
复现代码:
import pandas as pd import numpy as np people = pd.DataFrame({'id':[1,2,5,6], 'skills': [np.nan, "beta", "beta", "omega"], 'diploma': ["omicron", np.nan, "epsilon", "zeta"]}) jobs = pd.DataFrame({'id':[10,20,30,40], 'people_id':[1,2,3,4], 'skills': ["alpha", np.nan, "beta", "omega"], 'diploma': [np.nan, "zeta", "pi", "zeta"]})
解决方案
通过以下步骤实现需求:
- 合并DataFrame:执行内连接合并,合并后会生成带后缀的重复列(
_x来自people表,_y来自jobs表) - 填充NaN并合并重复列:用
combine_first方法优先保留jobs表的非空值,空缺处用people表的值填充 - 整理列结构:保留目标列并调整顺序、重命名
完整代码:
import pandas as pd import numpy as np # 原始数据 people = pd.DataFrame({'id':[1,2,5,6], 'skills': [np.nan, "beta", "beta", "omega"], 'diploma': ["omicron", np.nan, "epsilon", "zeta"]}) jobs = pd.DataFrame({'id':[10,20,30,40], 'people_id':[1,2,3,4], 'skills': ["alpha", np.nan, "beta", "omega"], 'diploma': [np.nan, "zeta", "pi", "zeta"]}) # 内连接合并 merged = pd.merge(people, jobs, left_on='id', right_on='people_id', how='inner') # 合并skills列:优先取jobs的非空值,空值用people表补充 merged['skills'] = merged['skills_y'].combine_first(merged['skills_x']) # 合并diploma列:逻辑同上 merged['diploma'] = merged['diploma_y'].combine_first(merged['diploma_x']) # 保留目标列并调整列名 result = merged[['id_y', 'people_id', 'skills', 'diploma']].rename(columns={'id_y': 'id'}) print(result)
执行后输出:
id people_id skills diploma 0 10 1 alpha omicron 1 20 2 beta zeta
代码说明
combine_first方法会自动将调用者(如skills_y)中的NaN值替换为被调用者(如skills_x)对应位置的有效值,完美匹配"双向填充NaN"的需求- 合并后将
id_y重命名为id,对应job的唯一标识,最终保留指定列即可得到目标结果
内容的提问来源于stack exchange,提问作者Bertrand
相关产品推荐
相关产品推荐

