如何用Pandas将小时观测数据转换为按日分组的小时列结构?
解决方案:Pandas内置方法实现小时数据转日维度宽表
当然可以!这种时间序列数据的宽表转换需求,Pandas提供了非常简洁的内置方案,核心是利用**层级索引(MultiIndex)+ unstack()或者pivot()**方法来实现,完全不需要额外写复杂循环。下面给你详细演示两种常用方法:
方法一:利用MultiIndex + unstack()
这是最直接的方式,先把原Series的时间索引拆分为「日期」和「小时」两个层级,再将小时层级展开为列。
步骤示例:
- 先构造和你示例一致的测试数据(模拟你的小时级Series):
import pandas as pd # 模拟你的小时观测数据 data = [45, 46, 47, 50, 51] timestamps = pd.to_datetime([ "2018-05-12 12:00", "2018-05-12 13:00", "2018-05-12 14:00", "2018-05-13 10:00", "2018-05-13 11:00" ]) hourly_series = pd.Series(data, index=timestamps, name="value")
- 将时间索引拆分为日期+小时的MultiIndex:
# 从原时间索引中提取日期和小时,生成双层索引 hourly_series.index = pd.MultiIndex.from_tuples( [(dt.date(), dt.hour) for dt in hourly_series.index], names=["date", "hour"] )
- 用
unstack()将小时层级转为列,并调整列名:
# 展开小时层级为列,缺失的小时会自动填充NaN daily_wide_df = hourly_series.unstack(level="hour") # 把列名改成你需要的value_xx格式 daily_wide_df.columns = [f"value_{hour}" for hour in daily_wide_df.columns] # 可选:将date从索引转为普通列 daily_wide_df = daily_wide_df.reset_index()
运行后得到的结果就是你想要的日维度宽表,每行对应一天,每列对应一个小时的数值。
方法二:使用pivot()方法
如果你更习惯DataFrame的操作,可以先把Series转为DataFrame,提取日期和小时列后用pivot()实现行转列:
# 将Series转为DataFrame,新增date和hour列 df = hourly_series.to_frame() df["date"] = df.index.date df["hour"] = df.index.hour # 执行pivot转换 daily_wide_df = df.pivot(index="date", columns="hour", values="value") # 重命名列并重置索引 daily_wide_df.columns = [f"value_{h}" for h in daily_wide_df.columns] daily_wide_df = daily_wide_df.reset_index()
补充说明
- 如果你的数据存在缺失的小时(比如某天只有部分时段有数据),
unstack()和pivot()会自动用NaN填充缺失值,你可以用fillna()指定填充值,比如daily_wide_df.fillna(0, inplace=True)来填充0。 - 两种方法本质逻辑一致,选择你觉得更直观的即可。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

