基于ID分组的DataFrame列条件式Back/Forward Fill问题
需求
- 按
id列对DataFrame分组 - 对
email_unconf列执行以下逻辑:- 若分组内
email_conf列存在非空值,用该列经过前后填充(Back/Forward Fill)后的值覆盖email_unconf - 若分组内
email_conf全为空,则直接对email_unconf列执行前后填充
- 若分组内
尝试的解决方案
def my_func(x): if merged['email_conf'].isnull().all(): return x.bfill().ffill() else: return merged['email_conf'].bfill().ffill() merged['email_unconf'] = merged.groupby('id')['email_unconf'].apply(my_func)
初始DataFrame
id email_unconf email_conf 5827553206045509 unc1@gmail.com NaN 5827553206045509 unc1@gmail.com NaN 5827553206045509 NaN NaN ... 5827553206045510 unc2@gmail.com NaN ...
期望结果DataFrame
id email_unconf email_conf 5827553206045509 conf1@gmail.com NaN ... 5827553206045510 unc2@gmail.com NaN ...
问题修正与正确实现
原代码存在两个核心问题:
- 在分组处理函数中错误引用全局
merged对象,而非当前分组的子DataFrame - 判断条件未针对当前分组的
email_conf列做检查
正确实现代码如下:
def process_group(group): # 检查当前分组的email_conf是否存在非空值 if not group['email_conf'].isnull().all(): # 对email_conf做前后填充后覆盖email_unconf filled_conf = group['email_conf'].bfill().ffill() return filled_conf else: # 直接对email_unconf做前后填充 return group['email_unconf'].bfill().ffill() # 按id分组处理并赋值回原列 merged['email_unconf'] = merged.groupby('id').apply(process_group).reset_index(level=0, drop=True)
代码说明
- 分组后每个子DataFrame会传入
process_group函数,确保逻辑针对单个分组生效 - 用
reset_index(level=0, drop=True)去掉分组产生的id索引,保证结果能正确匹配原DataFrame的行
内容的提问来源于stack exchange,提问作者S44
相关产品推荐
相关产品推荐

