Pandas中DateTimeIndex高效调整:实现跨日时间范围索引查询
高效调整pandas时间索引,实现跨日期时段查询
现有一个带5分钟间隔DateTimeIndex的pandas DataFrame,需要调整索引,让df.loc[特定日期]返回前一天18:00至该日期17:00的数据。比如df.loc['2019-01-02']要返回2019-01-01 18:00到2019-01-02 17:00的数据集。
原方法用循环拼接修改索引,数据量大(数千日期)时速度极慢,还可能出现索引缺失,求更高效的实现方式。
示例数据
import pandas as pd import numpy as np index = pd.date_range(start='2019-01-01 00:00', freq='5min', periods=500) df = pd.DataFrame({'x' : np.arange(len(index))}, index = index)
用户尝试的低效代码
dates = df.index.date data_l = [] for i in range(len(dates)-1): night_data = df[df.index.date == dates[i]].between_time('18:00', '23:55') day_data = df[df.index.date == dates[i]].between_time('00:00', '16:55') data = pd.concat([night_data, day_data], axis=0) data.index = data.index.map(lambda x : x.replace(day = dates[i+1].day)) data_l.append(data) df_reindexed = pd.concat(data_l, axis=0)
高效解决方案
核心思路是通过时间偏移给每个原始时间戳分配对应的目标日期索引,全程用向量化操作替代循环,大幅提升效率:
步骤说明
- 给每个时间戳标记对应的目标日期:
- 若时间在18:00及之后,目标日期为次日
- 若时间在18:00之前,目标日期为当日
- 将目标日期设为索引,即可通过
df.loc[日期]直接查询对应时段的数据
代码实现
import pandas as pd import numpy as np # 生成示例数据(如果已有数据可跳过此步) index = pd.date_range(start='2019-01-01 00:00', freq='5min', periods=500) df = pd.DataFrame({'x' : np.arange(len(index))}, index = index) # 1. 生成目标日期列 cutoff_time = pd.to_datetime('18:00').time() df['target_date'] = np.where( df.index.time >= cutoff_time, (df.index + pd.Timedelta(days=1)).date, df.index.date ) # 2. 设置目标日期为索引 df_reindexed = df.set_index('target_date') # 验证查询:获取2019-01-02对应的时段数据 print(df_reindexed.loc['2019-01-02'].index)
进阶:保留原时间戳作为二级索引
如果需要同时保留原始时间信息,可以设置多级索引:
df_reindexed = df.set_index(['target_date', df.index]) # 查询方式不变:df_reindexed.loc['2019-01-02']
优势
- 速度快:向量化操作避免循环,处理数千日期的数据集效率提升显著
- 鲁棒性强:自动处理原始数据中的时间缺失,不会生成无效索引
- 易维护:逻辑清晰,后续调整时段规则只需修改
cutoff_time即可
内容的提问来源于stack exchange,提问作者Saeed
相关产品推荐
相关产品推荐

