如何在Pandas中仅对节假日日期范围重采样至分钟级?
解决方案:仅针对节假日日期生成分钟级数据
我完全理解你的痛点——resample('T').ffill()会生成整个时间跨度内所有日期的分钟数据,包括非节假日,这显然不是你想要的。你需要的是只对每个节假日当天生成全天的分钟级记录,下面是两种高效的实现方法:
方法一:自定义函数+Explode展开
这种方法逻辑清晰,适合新手理解:
- 首先确保你的
day列是带时区的datetime类型(如果还不是的话):
import pandas as pd # 转换为带时区的datetime(保留原数据的时区信息) holidays['day'] = pd.to_datetime(holidays['day'])
- 定义一个函数,为每个节假日生成当天从00:00到23:59的所有分钟时间点:
def get_daily_minutes(row): # 获取当天的起始时间(00:00)和结束时间(23:59) day_start = row['day'].floor('D') day_end = day_start + pd.Timedelta(days=1) - pd.Timedelta(minutes=1) # 生成分钟级时间序列,严格保留时区信息 return pd.date_range(start=day_start, end=day_end, freq='T', tz=row['day'].tz)
- 生成分钟序列并展开:
# 为每行添加分钟序列列 holidays['minute_times'] = holidays.apply(get_daily_minutes, axis=1) # 展开序列,并重命名列,删除原日期列 holidays_minute = holidays.explode('minute_times').drop('day', axis=1).rename(columns={'minute_times': 'day'})
方法二:一行式简洁实现
如果你喜欢更紧凑的代码,可以用assign+lambda直接完成:
holidays_minute = ( holidays.assign( day=holidays['day'].apply( lambda x: pd.date_range( start=x.floor('D'), end=x.ceil('D') - pd.Timedelta(minutes=1), freq='T', tz=x.tz ) ) ) .explode('day') .reset_index(drop=True) )
为什么之前的方法无效?
holidays.resample('T').ffill():resample会以数据中最早和最晚的日期为边界,生成整个区间的时间索引,然后向前填充,所以会包含大量非节假日的日期。- 嵌套
resample的方法:apply(lambda x: x.resample('T').ffill())之所以失败,是因为在每行应用resample时,该行只有单个时间点,无法生成连续的时间序列,自然无法完成下采样操作。
验证结果
你可以检查某个节假日的记录数,应该正好是1440条(24小时×60分钟):
# 检查第一个节假日的分钟记录数 print(holidays_minute[holidays_minute['day'].dt.date == pd.to_datetime('2012-02-20').date()].shape[0]) # 输出应为1440
内容的提问来源于stack exchange,提问作者Maurice Kroon
相关产品推荐
相关产品推荐

