如何用asfreq()处理重复时间戳?保留夏令时重复时段的方法
解决ENTSO-E电力时间序列的DST缺口填补与重复时段保留问题
问题背景
从ENTSO-E透明度平台获取的多国多类型发电小时级数据存在时间序列不一致问题:部分时段因源页面缺失对应行导致序列中断。使用asfreq()方法可填补夏令时(DST)三月最后周日02:00这类缺失时段(用短横线填充),但在处理夏令时十月最后周日的重复02:00时段时,asfreq()无法兼容重复索引,必须调用drop_duplicates()导致该时段丢失,进而影响与电价、电力需求等数据集的联合分析。
复现代码
import pandas as pd import numpy as np # 生成单日小时级时间索引 date_rng = pd.date_range(start='2024-01-01', end='2024-01-02', freq='H') # 创建示例DataFrame df = pd.DataFrame(date_rng, columns=['date']) df['data'] = np.random.randn(len(df['date'])) # 生成随机数据 df.set_index('date', inplace=True) # 模拟三月DST缺失时段(删除部分行) df = df.drop(pd.to_datetime(['2024-01-01 03:00', '2024-01-01 07:00', '2024-01-01 11:00'])) # 模拟十月DST重复时段(插入重复行) duplicate_row = df.iloc[[5]] part_before = df.iloc[:6] # 保留原行的前半部分 part_after = df.iloc[6:] # 原行之后的部分 # 拼接生成带重复索引的DataFrame df = pd.concat([part_before, duplicate_row, part_after]).reset_index() df.rename(columns={'index':'date'},inplace=True) df.set_index('date', inplace=True)
当前DataFrame状态
| date | data |
|---|---|
| 2024-01-01 00:00:00 | 0.958687 |
| 2024-01-01 01:00:00 | -0.598715 |
| 2024-01-01 02:00:00 | 2.555558 |
| 2024-01-01 04:00:00 | 1.115459 |
| 2024-01-01 05:00:00 | -1.719786 |
| 2024-01-01 06:00:00 | -0.128536 |
| 2024-01-01 06:00:00 | -0.128536 |
| 2024-01-01 08:00:00 | -1.183776 |
需求目标
填补时间序列中的缺口(用短横线-填充缺失值),同时保留夏令时十月的重复时段(示例中的2024-01-01 06:00:00重复行),目标DataFrame如下:
| date | data |
|---|---|
| 2024-01-01 00:00:00 | 0.958687 |
| 2024-01-01 01:00:00 | -0.598715 |
| 2024-01-01 02:00:00 | 2.555558 |
| 2024-01-01 03:00:00 | - |
| 2024-01-01 04:00:00 | 1.115459 |
| 2024-01-01 05:00:00 | -1.719786 |
| 2024-01-01 06:00:00 | -0.128536 |
| 2024-01-01 06:00:00 | -0.128536 #duplicate |
| 2024-01-01 07:00:00 | - |
| 2024-01-01 08:00:00 | -1.183776 |
解决方案
核心思路是先构建完整时间序列框架,再合并原始数据(保留重复行),最后统一填补缺失值。
# 1. 生成完整的目标时间序列(包含所有应有的小时段) full_date_rng = pd.date_range(start='2024-01-01', end='2024-01-02', freq='H') full_df = pd.DataFrame(index=full_date_rng, columns=['data']) # 2. 将原始数据合并到完整框架中:保留所有重复行 df_reset = df.reset_index() merged_df = pd.merge(full_df.reset_index(), df_reset, on='date', how='outer', suffixes=('_full', '')) # 3. 填充缺失值为短横线 merged_df['data'] = merged_df['data'].fillna('-') # 4. 恢复索引并整理格式 merged_df.set_index('date', inplace=True) merged_df = merged_df[['data']] # 查看最终结果 print(merged_df)
说明
- 生成完整时间序列确保三月DST的缺口被覆盖;
- 用
outer merge保留原始数据中的重复行,避免十月DST时段丢失; - 最后统一填充缺失值,满足后续联合分析的数据格式要求。
内容的提问来源于stack exchange,提问作者g3nkoVMAESTRO
相关产品推荐
相关产品推荐

