Datetime格式索引排序:将每日首条数据设为1:00的问题排查
调整DataFrame Datetime索引:让每日1:00在前,0:00在后
需求说明
需要将Datetime索引的DataFrame调整为每日首条数据是1:00,最后一条是0:00——即把当天0:00的数据归属到前一天的末尾。
问题回顾
无效的初始尝试
直接修改0点索引的代码无法生效,因为.loc返回的是视图或副本,修改不会同步到原DataFrame:
curva_generacion.loc[curva_generacion.index.hour == 0].index = curva_generacion.loc[curva_generacion.index.hour == 0].index - pd.DateOffset(days=1)
拆分合并后的排序问题
后续尝试拆分0点和非0点数据,修改0点索引后合并,但默认按Datetime索引排序会让0点数据回到每日开头:
auxiliar1 = curva_generacion.loc[curva_generacion.index.hour == 0] auxiliar1.index = auxiliar1.index - pd.DateOffset(days=1) auxiliar1.index = auxiliar1.index.map(lambda t: t.replace(year=2015)) auxiliar2 = curva_generacion.loc[curva_generacion.index.hour != 0] curva_generacion = pd.concat([auxiliar1, auxiliar2]) curva_generacion.sort_index(inplace=True)
示例DataFrame结构:
**SVH.2.1 BIS** **FECHA** 2015-01-01 00:00:00 0.00 2015-01-01 01:00:00 0.00 ... 2015-01-02 02:00:00 0.00
解决方案
核心思路:先将0点数据的索引日期减1天,再通过自定义排序规则让1-23点数据在前,0点数据(归属前一天)在后。
方法一:添加辅助排序列(逻辑清晰)
import pandas as pd # 1. 拆分并处理0点数据(必须用copy避免视图修改问题) auxiliar1 = curva_generacion[curva_generacion.index.hour == 0].copy() auxiliar1.index = auxiliar1.index - pd.DateOffset(days=1) auxiliar2 = curva_generacion[curva_generacion.index.hour != 0].copy() # 2. 合并两个数据集 curva_generacion = pd.concat([auxiliar1, auxiliar2]) # 3. 添加辅助排序键:0点设为24,其他用原小时数 curva_generacion['sort_key'] = curva_generacion.index.hour curva_generacion.loc[curva_generacion['sort_key'] == 0, 'sort_key'] = 24 # 4. 按「日期」和「排序键」排序,确保1-23点在前,0点在后 curva_generacion.sort_values(by=[curva_generacion.index.date, 'sort_key'], inplace=True) # 5. 可选:删除辅助列 curva_generacion.drop(columns=['sort_key'], inplace=True)
方法二:直接用自定义排序元组(更简洁)
import pandas as pd # 先复制原DataFrame避免修改原数据 curva_generacion = curva_generacion.copy() # 处理0点数据的索引:日期减1天 mask = curva_generacion.index.hour == 0 curva_generacion.index = curva_generacion.index.where(~mask, curva_generacion.index - pd.DateOffset(days=1)) # 自定义排序规则:按(日期, 小时值)排序,0点替换为24确保排在最后 sorted_indices = curva_generacion.index.to_series().apply( lambda dt: (dt.date(), 24 if dt.hour == 0 else dt.hour) ).sort_values().index # 重新排序DataFrame curva_generacion = curva_generacion.loc[sorted_indices]
效果验证
处理后,每日数据的顺序会变为:2015-01-01 01:00:00 → ... → 2015-01-01 23:00:00 → 2015-01-01 00:00:00(原2015-01-02的0点数据,已调整日期)
内容的提问来源于stack exchange,提问作者nico
相关产品推荐
相关产品推荐

