如何按分类列分组对Pandas数据按规则执行前向与后向填充
按分类分组并基于Start/End标记填充Value列
需求说明
- 按
category列分组,每组内先按date排序 - 处理步骤:
- 当行的
value_stage为Start(不区分大小写)时,将该行的value**前向填充(ffill)**至后续的空值行 - 完成第一步后,当行的
value_stage为End(不区分大小写)时,将该行的value**后向填充(bfill)**至前面的空值行
- 当行的
- 补充:单个分类可包含多个对应不同value的Start/End标记
示例原数据
import pandas as pd df = pd.DataFrame([ ['2022-01-01','A','',''],['2022-01-02','A','3','End'],['2022-01-03','A','4','Start'],['2022-01-04','A','',''],['2022-01-05','A','2','Start'],['2022-01-06','A','',''],['2022-01-07','A','',''], ['2022-01-01','B','3','End'],['2022-01-02','B','',''],['2022-01-03','B','1','Start'],['2022-01-04','B','',''],['2022-01-05','B','',''],['2022-01-06','B','2','end'],['2022-01-07','B','',''], ['2022-01-01','C','',''],['2022-01-02','C','3','End'],['2022-01-03','C','',''],['2022-01-04','C','1','End'], ], columns = ['date', 'category', 'value','value_stage'])
期望输出数据
expected_df = pd.DataFrame([ ['2022-01-01','A','3',''],['2022-01-02','A','3','End'],['2022-01-03','A','4','Start'],['2022-01-04','A','4',''],['2022-01-05','A','2','Start'],['2022-01-06','A','2',''],['2022-01-07','A','2',''], ['2022-01-01','B','3','End'],['2022-01-02','B','',''],['2022-01-03','B','1','Start'],['2022-01-04','B','1',''],['2022-01-05','B','1',''],['2022-01-06','B','2','end'],['2022-01-07','B','',''], ['2022-01-01','C','3','End'],['2022-01-02','C','3','End'],['2022-01-03','C','1','End'],['2022-01-04','C','1','End'], ], columns = ['date', 'category', 'value','value_stage'])
输出说明
- 分类A:1月3日的Start值4前向填充到1月4日;1月2日的End值3后向填充到1月1日;1月5日的Start值2前向填充到1月6、7日
- 分类B:1月3日的Start值1前向填充到1月4、5日
- 分类C:1月2日的End值3后向填充到1月1日;1月4日的End值1后向填充到1月3日
解决方案
代码实现
import pandas as pd def fill_values(group): # 每组内按日期排序 group = group.sort_values('date').reset_index(drop=True) # 处理Start标记的前向填充 temp_start = group['value'].where(group['value_stage'].str.lower() == 'start') group['value'] = group['value'].mask(group['value'] == '', temp_start.ffill()) # 处理End标记的后向填充 temp_end = group['value'].where(group['value_stage'].str.lower() == 'end') group['value'] = group['value'].mask(group['value'] == '', temp_end.bfill()) return group # 按分类分组应用处理函数 result_df = df.groupby('category', group_keys=False).apply(fill_values)
代码解释
- 分组排序:确保每组内数据按日期顺序排列,保证填充逻辑的时间正确性
- Start前向填充:仅提取Start标记行的value,前向填充后替换后续空值,避免干扰其他标记的填充逻辑
- End后向填充:提取End标记行的value,后向填充后替换前面剩余的空值
- 合并结果:将各组处理后的数据合并,得到最终填充后的数据集
验证结果
可通过以下代码确认结果与期望一致:
print(result_df.equals(expected_df)) # 输出:True
内容的提问来源于stack exchange,提问作者tjt
相关产品推荐
相关产品推荐

