You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按分类列分组对Pandas数据按规则执行前向与后向填充

按分类分组并基于Start/End标记填充Value列

需求说明

  • 按category列分组,每组内先按date排序
  • 处理步骤:
    1. 当行的value_stage为Start(不区分大小写)时,将该行的value**前向填充(ffill)**至后续的空值行
    2. 完成第一步后,当行的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)

代码解释

  1. 分组排序:确保每组内数据按日期顺序排列,保证填充逻辑的时间正确性
  2. Start前向填充:仅提取Start标记行的value,前向填充后替换后续空值,避免干扰其他标记的填充逻辑
  3. End后向填充:提取End标记行的value,后向填充后替换前面剩余的空值
  4. 合并结果:将各组处理后的数据合并,得到最终填充后的数据集

验证结果

可通过以下代码确认结果与期望一致:

print(result_df.equals(expected_df))
# 输出:True

内容的提问来源于stack exchange,提问作者tjt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 00:07:08