如何合并日度与小时级日期索引的Pandas DataFrame?
问题描述
我有一份小时级价格数据集,先通过以下代码生成了每日最低价格的DataFrame:
df_min = df_hour_0[['Price_REG1', 'Price_REG2', 'Price_REG3', 'Price_REG4']].between_time('00:00', '23:00').resample('d').min()
生成的df_min结构如下:
Price_REG1 Price_REG2 Price_REG3 Price_REG4 date 2020-01-01 00:00:00 25.07 25.07 25.07 25.07 2020-01-02 00:00:00 12.07 12.07 12.07 12.07 2020-01-03 00:00:00 0.14 0.14 0.14 0.14 2020-01-04 00:00:00 3.83 3.83 3.83 3.83 2020-01-05 00:00:00 25.77 25.77 25.77 25.77
现在要把这个每日最低价格表和24个小时级DataFrame(比如hour_0)合并,hour_0结构示例:
Price_REG1 Price_REG2 ... Price_24_3 Price_24_4 date ... 2020-01-01 00:00:00 30.83 30.83 ... NaN NaN 2020-01-02 00:00:00 24.81 24.81 ... 25.88 25.88 2020-01-03 00:00:00 24.39 24.39 ... 27.69 27.69 2020-01-04 00:00:00 22.04 22.04 ... 25.70 25.70 2020-01-05 00:00:00 25.77 25.77 ... 27.37 27.37
用pd.concat合并时:
df_hour_0 = pd.concat([df_hour_0, df_min, df_max], axis=1)
只有日期为0点的hour_0能正常合并,其他小时的DataFrame(比如日期是2020-01-01 01:00:00)因为索引日期不匹配,合并后出现大量NaN:
Price_REG1 Price_REG2 ... Price_3_min Price_4_min date ... 2020-01-01 00:00:00 NaN NaN ... NaN NaN 2020-01-01 01:00:00 28.78 28.78 ... NaN NaN 2020-01-02 00:00:00 NaN NaN ... 30.83 30.83 2020-01-02 01:00:00 12.07 12.07 ... NaN NaN 2020-01-03 00:00:00 NaN NaN ... 31.20 31.20
尝试重置索引并删除日期列也没用,只会把df_min插到目标表底部,现在需要保留日期索引的有效合并方案。
解决方案
核心思路是将每日级别的df_min/df_max广播到对应日期的所有小时行上,确保索引匹配,具体有两种实现方式:
方式1:利用merge按日期键匹配
- 先处理每日最值表的索引,只保留日期部分:
# 转换df_min的索引为纯日期类型 df_min.index = df_min.index.date # 对df_max执行同样操作 df_max.index = df_max.index.date
- 为每个小时级DataFrame添加日期匹配键:
# 以任意小时级df(比如hour_1)为例,提取索引的日期部分作为匹配键 hour_1['date_key'] = hour_1.index.date
- 按日期键合并数据,保留原小时级索引:
# 合并df_min,添加_min后缀避免列名重复 hour_1 = hour_1.merge(df_min.add_suffix('_min'), left_on='date_key', right_index=True, how='left') # 合并df_max,添加_max后缀 hour_1 = hour_1.merge(df_max.add_suffix('_max'), left_on='date_key', right_index=True, how='left') # 可选:删除临时的date_key列 hour_1 = hour_1.drop('date_key', axis=1)
方式2:直接用索引映射关联
无需新增列,直接通过小时级索引的日期部分映射到每日最值:
# 为每日最值表的列添加后缀 df_min = df_min.add_suffix('_min') df_max = df_max.add_suffix('_max') # 把小时级df的索引日期映射到对应每日最值行,再合并 hour_1 = pd.concat([ hour_1, hour_1.index.date.map(df_min.loc).reset_index(drop=True), hour_1.index.date.map(df_max.loc).reset_index(drop=True) ], axis=1)
两种方式都能让当天所有小时的行匹配到对应的每日最低/最高价格,不会出现NaN,同时完整保留原有的小时级日期索引。
内容的提问来源于stack exchange,提问作者user20050294
相关产品推荐
相关产品推荐

