Pandas多时间戳索引处理与重采样技术咨询
Pandas多索引DataFrame扩展与填充实现方案
现有基础多索引DataFrame如下:
value A B C 111 2024-03-22 00:00:00 2024-03-22 00:00:00 1 111 2024-03-22 00:00:00 2024-03-22 01:00:00 2 111 2024-03-22 00:00:00 2024-03-22 02:00:00 3 222 2024-03-22 00:00:00 2024-03-22 03:00:00 4 222 2024-03-22 00:00:00 2024-03-22 04:00:00 5 222 2024-03-22 00:00:00 2024-03-22 05:00:00 6
其中:
- 索引
A为固定维度,需保留所有唯一值 - 索引
B为日级时间分组 - 索引
C为小时级时间分组
需结合两组时间范围扩展数据:
a) 日级时间(作为索引B):
2024-02-05 00:00:00 2024-02-06 00:00:00
b) 小时级时间(作为索引C,与对应B为同一天):
2024-02-05 22:00:00 2024-02-05 23:00:00 2024-02-06 22:00:00 2024-02-06 23:00:00
最终需生成包含所有A、B、C组合的目标DataFrame,原有数据保留原值,新增组合填充为0。
问题解答
1. 实现方案
核心思路是生成完整的多索引笛卡尔积,再与原数据合并填充缺失值,具体步骤如下:
步骤1:预处理基础数据
提取唯一A值并确保索引为datetime类型:
import pandas as pd # 假设基础数据已加载为df,先统一索引类型 df.index = df.index.set_levels([ df.index.levels[0], pd.to_datetime(df.index.levels[1]), pd.to_datetime(df.index.levels[2]) ]) # 提取所有唯一的A值 unique_A = df.index.get_level_values('A').unique()
步骤2:构建新增的(B, C)时间对
匹配新增日级B与对应小时级C:
# 转换新增时间为datetime类型 new_days = pd.to_datetime(['2024-02-05 00:00:00', '2024-02-06 00:00:00']) new_hours = pd.to_datetime(['2024-02-05 22:00:00', '2024-02-05 23:00:00', '2024-02-06 22:00:00', '2024-02-06 23:00:00']) # 生成同天的(B, C)配对 new_bc_pairs = [(day, hour) for day in new_days for hour in new_hours if hour.date() == day.date()]
步骤3:合并所有(B, C)对并生成完整索引
# 提取原数据中的(B, C)对 original_bc_pairs = list(df.index.droplevel('A').unique()) # 合并新旧(B, C)对 all_bc_pairs = new_bc_pairs + original_bc_pairs # 生成A与所有(B,C)的笛卡尔积索引 full_index = pd.MultiIndex.from_product( [unique_A, [pair[0] for pair in all_bc_pairs], [pair[1] for pair in all_bc_pairs]], names=['A', 'B', 'C'] )
步骤4:重新索引并填充缺失值
# 重新索引原数据,缺失值填充为0 result_df = df.reindex(full_index, fill_value=0) # 按索引排序(可选,匹配目标DataFrame的展示顺序) result_df = result_df.sort_index(level=['B', 'C', 'A'])
执行后即可得到目标DataFrame。
2. 使用date_range的合理性
非常合适,尤其适配你仅能获取单日起止日期/时间的场景:
- 生成日级
B:给定单日起止(如start='2024-02-05', end='2024-02-06'),可通过pd.date_range(start=start, end=end, freq='D')自动生成0点的日序列。 - 生成小时级
C:如需某一天的指定小时范围(如22-23点),用pd.date_range(start='2024-02-05 22:00:00', end='2024-02-05 23:00:00', freq='H')即可生成对应小时序列。 - 后续扩展到分钟级索引
D时,只需将freq改为'T'(分钟)生成对应序列,再加入多索引的笛卡尔积即可,逻辑完全复用。
内容的提问来源于stack exchange,提问作者OliverGras
相关产品推荐
相关产品推荐

