pandas如何高效计算月度均值并按小时粒度存储?
Pandas 时序数据月度均值填充最优实现
实现逻辑
全程采用pandas向量化运算,无逐小时、逐年、逐行循环,性能最优,核心逻辑分4步:
- 预处理原始时间字段,提取分组维度,先计算单条记录A-Z列的行均值
- 按「年+月」维度分组聚合,得到每个年份对应月份的A-Z列整体均值
- 生成平年全年逐小时的标准时间索引,格式统一为
月-日 时:分:秒,自动忽略闰年2月29日 - 通过关联+透视操作,把各年月度均值填充到对应月份的所有小时记录上,按年份展开为列
完整实现代码
import pandas as pd import numpy as np # 1. 原始数据预处理 # 强制转换时间字段为datetime类型 input_data['datetime'] = pd.to_datetime(input_data['datetime']) # 提取分组用的年、月维度 input_data['year'] = input_data['datetime'].dt.year input_data['month'] = input_data['datetime'].dt.month # 筛选A-Z所有数值列 value_cols = [col for col in input_data.columns if col.isupper() and len(col)==1] # 计算单条记录A-Z列的行均值 input_data['row_avg'] = input_data[value_cols].mean(axis=1) # 2. 聚合得到各年各月的A-Z整体均值 monthly_avg = input_data.groupby(['year', 'month'], as_index=False)['row_avg'].mean() monthly_avg.rename(columns={'row_avg':'mean_val'}, inplace=True) # 3. 生成平年逐小时标准时间索引(忽略闰年差异) # 选平年2015作为基准年,生成全年8760个小时级时间点 base_time = pd.date_range(start='2015-01-01 00:00:00', end='2015-12-31 23:00:00', freq='H') std_time = pd.DataFrame({ 'datetime': base_time.strftime('%m-%d %H:%M:%S'), 'month': base_time.month }) # 4. 关联透视得到最终输出 # 构造关联键做笛卡尔积,让每个月的标准时间点匹配所有年份的对应月均值 std_time['join_key'] = 1 monthly_avg['join_key'] = 1 merged_df = std_time.merge(monthly_avg, on=['join_key', 'month'], how='left') # 按年份透视成宽表 output = merged_df.pivot(index='datetime', columns='year', values='mean_val').reset_index() # 清理列名,按年份升序排列 output.columns.name = None year_cols = sorted([col for col in output.columns if isinstance(col, int)]) output = output[['datetime'] + year_cols]
补充说明
如果需要保留闰年2月29日的时间点,只需要把基准时间的生成年份替换为闰年(如2016、2020)即可,其余逻辑不需要调整。
内容的提问来源于stack exchange,提问作者fidu13
相关产品推荐
相关产品推荐

