如何用Pandas的Pivot与Groupby生成月均小时数据
问题解决:按小时分组计算各月份对应小时的平均值
问题描述
现有一个以datetime index为索引的DataFrame(仅含单列数据),需要将其重塑为以小时为索引、月份(1-12)为列的结构,计算每个月对应小时的平均值,最终得到各月份的小时均值数据。当前代码仅能算出全年小时平均值,无法生成分月份的列,需修正实现方法。
用户尝试代码
尝试代码1
import pandas as pd import numpy as np dti = pd.date_range("2018-01-01", periods=8760, freq="H") np.random.seed(seed=1111) data = np.random.randint(1, high=100, size=len(dti)) data1 = np.random.randint(1, high=100, size=len(dti)) data2 = np.random.randint(1, high=100, size=len(dti)) data3 = np.random.randint(1, high=100, size=len(dti)) df = pd.DataFrame({'date': dti, 'data': data, 'data1': data1, 'data2': data2, 'data3': data3 }) df = df.set_index('date') df1 = df[['data']] pd.pivot(df1,index=df1.index.hour,columns=df1.index.month) df1 = df1.groupby(df1.index.hour).mean() print(df1)
尝试代码2
import pandas as pd import numpy as np dti = pd.date_range("2018-01-01", periods=8760, freq="H") np.random.seed(seed=1111) data1 = np.random.randint(1, high=100, size=len(dti)) data2 = np.random.randint(1, high=100, size=len(dti)) data3 = np.random.randint(1, high=100, size=len(dti)) data4 = np.random.randint(1, high=100, size=len(dti)) df = pd.DataFrame({'date': dti, 'data1': data1, 'data2': data2, 'data3': data3, 'data4': data4 }) df = df.set_index('date') df1 = df[['data1']] #pd.pivot(df1,index=df1.index.hour,columns=df1.index.month, values=df1[["data1"]]) df1 = df1.groupby(df1.index.hour).mean() #print(df1)
当前输出
data1 date 0 47.873973 1 49.454795 2 50.810959 3 48.726027 4 49.654795 5 49.745205 6 50.342466 7 47.753425 8 46.515068 9 49.364384 10 53.583562 11 49.983562 12 50.178082 13 51.049315 14 49.813699 15 51.032877 16 49.501370 17 49.641096 18 49.463014 19 48.504110 20 49.621918 21 51.060274 22 48.736986 23 50.139726
正确实现方案
核心逻辑是同时按小时和月份分组计算均值,再通过unstack将月份维度转为列,最终得到目标结构。
完整代码
import pandas as pd import numpy as np # 生成测试数据(保持与原代码一致的随机种子) dti = pd.date_range("2018-01-01", periods=8760, freq="H") np.random.seed(seed=1111) data = np.random.randint(1, high=100, size=len(dti)) # 构建datetime索引的单列DataFrame df = pd.DataFrame({'data': data}, index=dti) # 关键步骤:按小时+月份分组求均值,将月份转为列 result = df.groupby([df.index.hour, df.index.month])['data'].mean().unstack(level=1) # 可选:给列重命名为更直观的格式 result.columns = [f'月份{month}' for month in result.columns] print(result)
代码说明
- 分组逻辑:
groupby([df.index.hour, df.index.month])同时按小时和月份分组,确保计算的是每个月内每个小时的平均值,而非全年小时均值。 - 重塑结构:
.unstack(level=1)将分组后的月份(第二个分组维度)从多层索引转为列,直接得到以小时为行、月份为列的表格。 - 列名优化:通过列表推导式将列名从数字改为
月份1、月份2这类更易读的格式。
预期输出示例
月份1 月份2 月份3 月份4 月份5 月份6 月份7 月份8 月份9 月份10 月份11 月份12 0 48.354839 45.535714 49.096774 48.583333 47.935484 47.250000 48.096774 47.387097 47.083333 48.225806 47.516129 48.903226 1 52.129032 48.714286 49.225806 48.750000 49.000000 49.083333 48.000000 48.225806 49.333333 49.516129 47.096774 50.000000 2 52.096774 51.214286 52.032258 50.583333 50.129032 49.916667 50.000000 50.290323 50.166667 50.000000 49.032258 49.000000 ...
内容的提问来源于stack exchange,提问作者Moose Drool
相关产品推荐
相关产品推荐

