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

如何基于Pandas DataFrame不同行值修改StateHoliday列标记假期前日期

Pandas批量标记假期前期的实现方法

核心思路是先提取目标假期的所有日期,自动生成对应前置日期窗口,再批量匹配修改分类值,完全不用手动逐个改日期。

具体实现步骤

  • 第一步:先把日期列转换为Pandas datetime格式,确保日期运算正常
df['Date'] = pd.to_datetime(df['Date'])
  • 第二步:提取目标假期的所有日期,以复活节(对应StateHoliday值为b)为例
easter_dates = df[df['StateHoliday'] == 'b']['Date'].unique()
  • 第三步:生成需要标记的前置日期集合,比如要标记复活节前3天的日期
pre_holiday_days = 3
pre_easter_dates = set()

for holiday_date in easter_dates:
    # 生成从假期前1天往前数N天的日期序列,不包含假期当天
    pre_date_range = pd.date_range(
        end=holiday_date - pd.Timedelta(days=1),
        periods=pre_holiday_days
    )
    pre_easter_dates.update(pre_date_range)
  • 第四步:批量修改StateHoliday列的值
    注意如果StateHoliday是Categorical分类类型,需要先添加新的分类值,否则会赋值失败:
# 新增复活节前期的分类值,若列为object类型可跳过该行
df['StateHoliday'] = df['StateHoliday'].cat.add_categories(['b-'])

# 匹配前置日期批量赋值
df.loc[df['Date'].isin(pre_easter_dates), 'StateHoliday'] = 'b-'

多假期通用封装

如果需要给多个假期添加前期标记,可以直接用封装好的函数,传入对应假期编码和提前天数即可:

def mark_pre_holiday(df, holiday_code, pre_days=3):
    pre_code = f"{holiday_code}-"
    # 提取该类假期的所有日期
    holiday_dates = df[df['StateHoliday'] == holiday_code]['Date'].unique()
    # 生成前置日期集合
    pre_dates = set()
    for d in holiday_dates:
        pre_range = pd.date_range(end=d - pd.Timedelta(days=1), periods=pre_days)
        pre_dates.update(pre_range)
    # 分类列新增类别
    if isinstance(df['StateHoliday'].dtype, pd.CategoricalDtype):
        df['StateHoliday'] = df['StateHoliday'].cat.add_categories([pre_code])
    # 赋值
    df.loc[df['Date'].isin(pre_dates), 'StateHoliday'] = pre_code
    return df

# 调用示例:标记复活节前3天、圣诞节(假设编码为c)前2天
df = mark_pre_holiday(df, 'b', pre_days=3)
df = mark_pre_holiday(df, 'c', pre_days=2)

注意事项

  • 如果出现多个假期的前置日期重叠的情况,后执行的赋值会覆盖之前的结果,你可以按照优先级调整调用顺序
  • 如果需要排除门店未营业的日期,在赋值的筛选条件中加df['Open'] == 1即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 06:09:03