Pandas按name分组后用同组前向非空值填充job、age列空值
实现按分组取最后非空值填充指定列
数据构造复现
首先复现你提到的带新增空行的数据集,代码如下:
import pandas as pd import numpy as np # 初始原始数据 data = {'name': ['Alex', 'Ben', 'Marry','Alex', 'Ben', 'Marry'], 'job': ['teacher', 'doctor', 'engineer','teacher', 'doctor', 'engineer'], 'age': ['27', '32', '78','27', '32', '78'], 'weight': ['160', '209', '130','164', '206', '132'], 'date': ['6-12-2022', '6-12-2022', '6-12-2022','6-13-2022', '6-13-2022', '6-13-2022'] } df = pd.DataFrame(data) # 追加6-14-2022的全空行 add_data = pd.DataFrame({ 'name': df['name'].unique(), 'job': np.nan, 'age': np.nan, 'weight': np.nan, 'date': '6-14-2022' }) df = pd.concat([df, add_data], ignore_index=True)
可行实现方案
方案1:分组前向填充(适配当前场景,代码最简效率最高)
你当前新增的空行全部位于每个name分组的末尾,直接用分组ffill()(前向填充)即可,逻辑是沿行顺序向前找第一个非空值填充,刚好匹配“取组内最后一个非空值填充”的需求,且不会改动不需要填充的weight列:
# 仅对job、age两列,按name分组做前向填充 df[['job', 'age']] = df.groupby('name')[['job', 'age']].ffill()
执行后6-14日期的三行填充结果:
- Alex:job=teacher,age=27,weight保持NaN
- Ben:job=doctor,age=32,weight保持NaN
- Marry:job=engineer,age=78,weight保持NaN
注意:使用前请确保DataFrame已经按
date字段升序排序,否则可能因为行顺序错乱取到错误的“最后一个值”。
方案2:分组取末位有效值映射(适配空值位置不固定的场景)
如果后续你的空值不一定插在每个分组的最末尾,可以用这个方案,鲁棒性更强:
# 按name分组,提取每组job、age列的最后一个非空值 last_valid_map = df.groupby('name')[['job', 'age']].last() # 遍历列做映射填充 for col in ['job', 'age']: df[col] = df.apply(lambda x: last_valid_map.loc[x['name'], col] if pd.isna(x[col]) else x[col], axis=1)
这个方法不管空值出现在组内哪个位置,都能正确匹配到该组对应列的最后一个非空值完成填充。
内容的提问来源于stack exchange,提问作者mnm
相关产品推荐
相关产品推荐

