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

咨询高效Pandas实现:统计各事件起止日期内的节假日数量

高效统计事件日期范围内的节假日数量

问题背景

现有两个DataFrame:

  • df1:存储事件名称及起止日期(Event列可能重复)
  • df2:存储所有节假日日期

需要统计每个事件的起止日期(含两端)内包含的节假日数量,原逐行apply的方法在数据量大时效率极低。

示例数据

import pandas as pd
from datetime import datetime

df1 = pd.DataFrame({"Event": ["S1", "K1", "S2", "S3", "A1"],
                    "Start": [datetime(2022,1,4), datetime(2022,1,15), datetime(2022,9,12), datetime(2022,11,11), datetime(2022,5,29)],
                    "End": [datetime(2022,1,19), datetime(2022,1,29), datetime(2022,9,27), datetime(2022,11,22), datetime(2022,6,15)]
                   })
df2 = pd.DataFrame({"Holidays": [datetime(2022,1,1), datetime(2022,1,6), datetime(2022,1,13), datetime(2022,6,10)]})

高效解决方案

方法一:广播+布尔索引分组计数

利用numpy广播机制实现向量化比较,避免逐行循环:

# 给df1添加临时索引用于后续分组
df1['temp_idx'] = df1.index

# 广播判断每个节假日是否落在对应事件的日期区间内
mask = (df2['Holidays'].values[:, None] >= df1['Start'].values) & (df2['Holidays'].values[:, None] <= df1['End'].values)

# 统计每个事件区间内的节假日数量,合并回原DataFrame
holiday_counts = pd.DataFrame(mask.T, index=df1['temp_idx']).sum(axis=1).rename('holiday_count')
df1 = df1.merge(holiday_counts, left_on='temp_idx', right_index=True).drop('temp_idx', axis=1)

方法二:IntervalIndex快速匹配计数

通过创建区间索引定位节假日所属事件,再统计数量:

# 创建包含所有事件区间的索引(闭区间)
event_intervals = pd.IntervalIndex.from_arrays(df1['Start'], df1['End'], closed='both')

# 查找每个节假日对应的事件区间索引,过滤无效匹配(-1表示不在任何区间)
holiday_interval_idx = event_intervals.get_indexer(df2['Holidays'])
valid_idx = holiday_interval_idx[holiday_interval_idx != -1]

# 统计每个事件的节假日数量,无匹配的补0
holiday_counts = pd.Series(valid_idx).value_counts().reindex(df1.index, fill_value=0).rename('holiday_count')
df1['holiday_count'] = holiday_counts

效果说明

两种方法均采用向量化操作,避免了apply的逐行处理,在大规模数据场景下效率远高于原方法,且不会出现内存占用过高的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 12:07:42