基于多条件的Pandas ffill/bfill数据填充问题求助
问题与解决方案
问题描述
现有数据集:
import pandas as pd condition=[None,None,None,'condition1',None,None,None,'condition2',None,None,None] add_val = [None,None,None,10,None,None,None,20,None,None,None] df=pd.DataFrame({'event_condition':condition,'add_col':add_val})
需要根据event_condition的条件对add_col进行缺失值填充,具体要求:
- 当遇到
condition1时,在独立列on_condition1中使用对应add_col的值(10)进行前向填充,不受condition2影响; - 当遇到
condition2时,在独立列on_condition2中使用对应add_col的值(20)进行前向填充,不受condition1影响; - 未遇到对应条件的位置,用0进行后向填充,且条件触发的行需保留为
None。
尝试过groupby方法但未成功:
df.groupby(df['event_condition'].eq(cond).cumsum())['add_col'].ffill()
期望得到如下结果:
condition=[None,None,None,'condition1',None,None,None,'condition2',None,None,None] add_val = [None,None,None,10,None,None,None,20,None,None,None] on_cond1=[0,0,0,None,10,10,10,None,10,10,10] on_cond2=[0,0,0,None,0,0,0 ,None,20,20,20] df=pd.DataFrame({'event_condition':condition,'add_col':add_val,'on_condition1':on_cond1,'on_condition2':on_cond2})
解决方法
通过分步骤处理每一列,结合mask、ffill和bfill可以实现需求:
import pandas as pd # 初始化数据集 condition=[None,None,None,'condition1',None,None,None,'condition2',None,None,None] add_val = [None,None,None,10,None,None,None,20,None,None,None] df=pd.DataFrame({'event_condition':condition,'add_col':add_val}) # 处理on_condition1列 df['on_condition1'] = df['add_col'].mask(df['event_condition'] != 'condition1') df['on_condition1'] = df['on_condition1'].ffill() # 对condition1触发前的行用0填充 first_cond1_idx = df[df['event_condition'] == 'condition1'].index[0] df['on_condition1'][:first_cond1_idx] = df['on_condition1'][:first_cond1_idx].fillna(0) # 把condition1触发的行设为None df.loc[df['event_condition'] == 'condition1', 'on_condition1'] = None # 剩余NaN(condition2触发的行)保留None,其他用之前的填充值 # 处理on_condition2列 df['on_condition2'] = df['add_col'].mask(df['event_condition'] != 'condition2') df['on_condition2'] = df['on_condition2'].ffill() # 对condition2触发前的行用0填充 first_cond2_idx = df[df['event_condition'] == 'condition2'].index[0] df['on_condition2'][:first_cond2_idx] = df['on_condition2'][:first_cond2_idx].fillna(0) # 把condition2触发的行设为None df.loc[df['event_condition'] == 'condition2', 'on_condition2'] = None # 未填充的NaN用0替换 df['on_condition2'] = df['on_condition2'].fillna(0) # 最后补全on_condition1的0填充 df['on_condition1'] = df['on_condition1'].fillna(0)
代码说明
- mask筛选目标值:仅保留对应条件行的
add_col值,其余设为NaN,确保后续填充只基于目标条件的值。 - 前向填充(ffill):实现条件触发后的值持续向下填充。
- 分段填充0:对条件触发前的行单独用0填充,避免影响触发后的填充逻辑。
- 重置条件行值:将触发条件的行重新设为
None,匹配预期格式。
运行代码后即可得到与期望一致的DataFrame。
内容的提问来源于stack exchange,提问作者stat_man
相关产品推荐
相关产品推荐

