Python:如何基于前序数据替换循环中DataFrame的数值
问题:DataFrame按日填充0值为当日00:00时刻的均值
我需要对一个较大的DataFrame执行数值替换操作。目标DataFrame为C,其中00:00时刻的数值为当日均值,希望将该数值重复填充至当日后续24小时的0值位置,使当日所有时刻数值一致。
我尝试的代码(无法实现预期效果)
C = q.merge(ss, how='right',left_index=True, right_index=True) C = C.fillna(0) for index, row in C['H04_PEDRO_MARIN'].iteritems(): if row == 0.0: C.replace({'H04_PEDRO_MARIN':{0.0:'Valor Anterior'}),inplace = True) else: None
当前数据与期望效果
当前DataFrame示例:
29/07/11 21:00 0 29/07/11 22:00 0 29/07/11 23:00 0 30/07/11 00:00 27658,625 30/07/11 01:00 0 ... 31/07/11 00:00 32617,125 31/07/11 01:00 0 ...
期望实现的效果:
29/07/11 21:00 0 29/07/11 22:00 0 29/07/11 23:00 0 30/07/11 00:00 27658,625 30/07/11 01:00 27658,625 ... 31/07/11 00:00 32617,125 31/07/11 01:00 32617,125 ...
解决方案
你的循环代码有两个核心问题:一是replace会把所有0.0统一替换成固定值,无法动态取当日0点的均值;二是循环遍历大DataFrame效率极低。推荐用pandas的时间序列分组填充方法,高效解决需求:
步骤1:确保索引为时间类型
先确认DataFrame的索引是datetime格式,若不是则转换:
import pandas as pd import numpy as np C.index = pd.to_datetime(C.index, format='%d/%m/%y %H:%M')
方法一:提取日均值后向前填充(高效推荐)
# 提取每日00:00的数值,其他位置设为NaN daily_mean = C['H04_PEDRO_MARIN'].where(C.index.hour == 0) # 向前填充,让全天每个时间点都对应当日0点的均值 filled_daily_mean = daily_mean.ffill() # 把原列的0值替换为对应均值,保留原本非0的历史数据(比如29日晚的0) C['H04_PEDRO_MARIN'] = C['H04_PEDRO_MARIN'].replace(0, np.nan).combine_first(filled_daily_mean).fillna(0)
方法二:按日期分组填充(逻辑直观)
# 按日期分组,每组内用00:00的数值替换组内的0值 C['H04_PEDRO_MARIN'] = C.groupby(C.index.date)['H04_PEDRO_MARIN'].apply( lambda x: x.replace(0, x[x.index.hour == 0].iloc[0]) if not x[x.index.hour == 0].empty else x )
说明
- 两种方法都无需循环,处理大DataFrame的效率远高于原代码
- 方法一利用向前填充的特性,计算速度更快;方法二按日期分组,逻辑更易理解
- 都会保留29日晚未到次日0点的0值,符合你的期望效果
内容的提问来源于stack exchange,提问作者Guille GL
相关产品推荐
相关产品推荐

