如何用对应小时均值替换时间序列数据中consumption列的零值
如何用对应小时均值替换时间序列中的零值
问题背景
现有时间序列DataFrame,需将consumption列的零值替换为该记录对应hour的全局均值:
原DataFrame示例:
date consumption hour 2017-09-18 13:00:00 0 13 2017-09-18 14:00:00 5 14 2017-09-18 15:00:00 8 15 2017-09-18 16:00:00 0 16 ... 2022-01-01 05:00:00 0 5 2022-01-01 06:00:00 16 6
已预先计算好各小时的consumption均值表:
hour consumption 0 1.5 1 2.6 2 2.9 ... 13 12.5 ... 5 2.8 ... 23 2.5
期望替换后,对应小时的零值被替换为该小时均值,例如13点的0替换为12.5,5点的0替换为2.8。
原代码问题分析
你尝试的代码无法生效的原因是:
df['consumption'].replace(0, df.groupby(by='hour')['consumption'].mean())
df.groupby('hour')['consumption'].mean()返回的是以hour为索引的Series,但replace(0, ...)是按值全局替换,无法将每行的hour与均值Series的索引关联,因此无法实现按小时匹配替换。
正确解决方案
方案1:使用预先给定的小时均值表
先将均值表转换为小时-均值的字典映射,再通过hour列匹配替换零值:
- 转换均值表为字典:
# 假设预先的均值表名为 hour_means_df hour_mean_map = hour_means_df.set_index('hour')['consumption'].to_dict()
- 使用
np.where替换零值:
import numpy as np df['consumption'] = np.where( df['consumption'] == 0, # 筛选零值行 df['hour'].map(hour_mean_map), # 匹配对应小时的均值 df['consumption'] # 非零值保持不变 )
或者使用pandas的mask方法(逻辑相反,替换满足条件的值):
df['consumption'] = df['consumption'].mask( df['consumption'] == 0, df['hour'].map(hour_mean_map) )
方案2:直接从原数据计算小时均值(无预先均值表)
如果没有预先计算好的均值表,可以直接从原DataFrame计算各小时的consumption均值(建议排除零值,避免拉低均值):
# 计算各小时的均值(排除零值) hour_means = df[df['consumption'] != 0].groupby('hour')['consumption'].mean() # 转换为字典映射 hour_mean_map = hour_means.to_dict() # 替换零值 df['consumption'] = np.where(df['consumption'] == 0, df['hour'].map(hour_mean_map), df['consumption'])
替换结果示例
执行后,目标行的零值将被正确替换:
date consumption hour 2017-09-18 13:00:00 12.5 13 2017-09-18 14:00:00 5 14 2017-09-18 15:00:00 8 15 2017-09-18 16:00:00 9.4 16 ... 2022-01-01 05:00:00 2.8 5 2022-01-01 06:00:00 16 6
内容的提问来源于stack exchange,提问作者Biswas
相关产品推荐
相关产品推荐

