如何在分组DataFrame中按条件使用ffill执行fillna填充
解决方案
需求明确
仅对Person为Bill且result为True的行,将其NaN值用Bill同分组内上一行的对应列数值填充(纵向向前填充),其他行的NaN保持不变。
错误原因分析
- 方法一问题:
groupby.transform是对分组的每一列执行函数,你试图在lambda中操作整个分组的DataFrame,且x['result'] == True返回的是布尔Series,无法直接作为if的判断条件;同时transform要求返回与原数据同形状的结果,逻辑不匹配需求。 - 方法二问题:
apply默认axis=0(按列处理),此时lambda参数是列的Series,不存在'result'键,导致KeyError。即使改为axis=1(按行处理),也无法直接实现同Person分组内的纵向填充逻辑。
通用解决代码
通过groupby.apply针对每个Person分组处理,适配Bill有多个result=True行的场景:
import pandas as pd import numpy as np df = pd.DataFrame( [["Bill", False, 13, 10, 15], ["Jane", False, 63, 17, 95], ["Bill", True, np.nan, 5, np.nan], ["Mary", False, 65, 13, np.nan]], columns=['Person','result','data1','data2','data3']) def process_group(group): # 筛选分组内需要填充的行 fill_mask = group['result'] == True if not fill_mask.any(): return group # 对分组内数值列做纵向向前填充,再替换目标行 filled_data = group[['data1', 'data2', 'data3']].ffill() group.loc[fill_mask, ['data1', 'data2', 'data3']] = filled_data.loc[fill_mask] return group # 按Person分组处理,group_keys=False避免保留分组索引 df2 = df.groupby('Person', group_keys=False).apply(process_group) print(df2)
执行结果:
Person result data1 data2 data3 0 Bill False 13.0 10 15.0 1 Jane False 63.0 17 95.0 2 Bill True 13.0 5 15.0 3 Mary False 65.0 13 NaN
简洁写法(适用于Bill仅两行场景)
直接定位目标行,用Bill上一行的数值填充:
# 筛选目标行 target_mask = (df['Person'] == 'Bill') & (df['result'] == True) # 填充指定列的NaN df.loc[target_mask, ['data1', 'data3']] = df[df['Person'] == 'Bill'].iloc[0][['data1', 'data3']].values
内容的提问来源于stack exchange,提问作者The Rhyno
相关产品推荐
相关产品推荐

