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

基于Pandas计算DataFrame日期区间内的节假日天数

正确计算日期区间内节假日天数的Pandas实现

初始数据表

num_IDstart_dateend_datetime
12022-02-102022-02-110 days 09:23:00
12022-02-122022-02-152 days 12:23:00
22022-02-122022-02-152 days 10:23:00
22022-02-052022-02-2722 days 02:35:00
32022-02-042022-02-061 days 19:55:00
32022-02-122022-02-152 days 05:21:00
32022-02-122022-02-152 days 05:15:00

节假日表

该表包含连续日期及节假日标记,省略行的is_holiday值均为False:

dateis_holidaynameother
2022-01-01TrueABCred
2022-01-02FalseCNAblue
............
2022-02-15TrueOOOred
2022-02-16TruePOOred
2022-02-17FalseKTYblue
............
2023-12-30FalseTTEwhite
2023-12-31TrueVVVred

需求

为初始数据表新增total_days列,统计每行start_date至end_date区间内(包含两端日期),节假日表中is_holiday=True的总天数。此前的方案存在计算错误,以下是正确实现方法。


实现代码

import pandas as pd

# 初始化初始数据表(实际场景可直接读取已有数据)
df_initial = pd.DataFrame({
    'num_ID': [1,1,2,2,3,3,3],
    'start_date': ['2022-02-10','2022-02-12','2022-02-12','2022-02-05','2022-02-04','2022-02-12','2022-02-12'],
    'end_date': ['2022-02-11','2022-02-15','2022-02-15','2022-02-27','2022-02-06','2022-02-15','2022-02-15'],
    'time': ['0 days 09:23:00','2 days 12:23:00','2 days 10:23:00','22 days 02:35:00','1 days 19:55:00','2 days 05:21:00','2 days 05:15:00']
})

# 初始化节假日表(实际场景可直接读取已有数据)
df_holidays = pd.DataFrame({
    'date': ['2022-01-01','2022-01-02','2022-02-15','2022-02-16','2022-02-17','2023-12-30','2023-12-31'],
    'is_holiday': [True, False, True, True, False, False, True],
    'name': ['ABC','CNA','OOO','POO','KTY','TTE','VVV'],
    'other': ['red','blue','red','red','blue','white','red']
})

# 1. 转换日期列为datetime类型,确保日期格式统一
df_initial['start_date'] = pd.to_datetime(df_initial['start_date'])
df_initial['end_date'] = pd.to_datetime(df_initial['end_date'])
df_holidays['date'] = pd.to_datetime(df_holidays['date'])

# 2. 提取所有节假日日期存入集合,提升查询效率
holiday_set = set(df_holidays.loc[df_holidays['is_holiday'], 'date'])

# 3. 定义函数计算单一行的节假日天数
def calc_holiday_count(row):
    # 生成区间内所有日期(包含起始和结束日期)
    date_range = pd.date_range(start=row['start_date'], end=row['end_date'], inclusive='both')
    # 统计落在节假日集合中的日期数量
    return sum(1 for dt in date_range if dt in holiday_set)

# 4. 应用函数生成total_days列
df_initial['total_days'] = df_initial.apply(calc_holiday_count, axis=1)

# 输出结果
print(df_initial)

代码说明

  • 日期类型转换:确保两个表的日期列都是datetime类型,避免字符串匹配错误。
  • 集合存储节假日:集合的查询时间复杂度为O(1),比遍历DataFrame效率更高,适合数据量较大的场景。
  • 精确日期区间生成:用pd.date_range生成包含两端的完整日期序列,确保每个日期都被检查,避免仅通过天数差计算导致的误差。

预期结果示例

以初始数据表前两行为例:

  • 第一行区间2022-02-10至2022-02-11无节假日,total_days=0
  • 第二行区间2022-02-12至2022-02-15包含节假日2022-02-15,total_days=1

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 16:25:38