如何用另一组列的值填充DataFrame中指定列的空缺值?
问题:用Pn列填充En列空缺并满足指定条件
原始数据
代码定义
import pandas as pd df_original = pd.DataFrame({ 'P1':['','',1,''], 'P2':[4,2,'',3], 'P3':[48,20,10,''], 'P4':['',320,160,264], 'E1':['','',1,3], 'E2':[4,2,10,264], 'E3':[48,20,'',528], 'E4':['','','',792], 'E5':['','','',''] })
表格展示
| P1 | P2 | P3 | P4 | E1 | E2 | E3 | E4 | E5 | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 4 | 48 | 4 | 48 | |||||
| 1 | 2 | 20 | 320 | 2 | 20 | ||||
| 2 | 1 | 10 | 160 | 1 | 10 | ||||
| 3 | 3 | 264 | 3 | 264 | 528 | 792 |
需求说明
- En组列中已存在的值,不能被Pn组列的值覆盖
- En组列的空缺需用Pn中未在En出现过的值填充,不允许向左缩进(即保持E列原有非空值的位置不变)
期望结果
| P1 | P2 | P3 | P4 | E1 | E2 | E3 | E4 | E5 | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 4 | 48 | 4 | 48 | |||||
| 1 | 2 | 20 | 320 | 2 | 20 | 320 | |||
| 2 | 1 | 10 | 160 | 1 | 10 | 160 | |||
| 3 | 3 | 264 | 3 | 264 | 528 | 792 |
解决方案
实现代码
import pandas as pd import numpy as np # 替换空字符串为NaN,便于缺失值处理 df = df_original.replace('', np.nan) # 分离P组和E组列 p_cols = [col for col in df.columns if col.startswith('P')] e_cols = [col for col in df.columns if col.startswith('E')] # 逐行处理填充逻辑 for idx, row in df.iterrows(): # 获取当前行P列的非空数值,保持原有顺序 p_values = row[p_cols].dropna().astype(int).tolist() # 获取当前行E列已存在的数值 e_existing = row[e_cols].dropna().astype(int).tolist() # 筛选出P中未在E里出现的候选填充值 fill_candidates = [val for val in p_values if val not in e_existing] # 获取E列的空缺位置(NaN对应的列名) empty_e_cols = row[e_cols][row[e_cols].isna()].index.tolist() # 按顺序将候选值填入空缺位置,直到候选值用完或空缺被填满 for val, col in zip(fill_candidates, empty_e_cols): df.loc[idx, col] = val # 将NaN换回空字符串,还原原始格式 df_result = df.replace(np.nan, '') print(df_result)
思路说明
- 预处理:把空字符串转为
NaN,利用pandas的缺失值处理方法简化操作 - 列分离:将P组和E组列分开,避免处理时混淆
- 逐行处理:
- 提取当前行P的有效数值,过滤掉E中已存在的值,得到可用于填充的候选值
- 定位E列的空缺位置,按顺序将候选值填入,确保不会覆盖E列已有值
- 格式还原:将处理后的
NaN换回空字符串,匹配原始数据格式
内容的提问来源于stack exchange,提问作者HedgeHog
相关产品推荐
相关产品推荐

