如何用对应分钟的均值填充时间序列数据集的NaN值?
解决方案:按时分秒分组填充对应缺失值
你遇到的问题是因为直接用fillna会全局替换所有NaN,而我们需要只针对每个特定时分秒的组,用组内均值填充组内的缺失值。下面是具体的实现方法,结合你的示例数据来讲解:
第一步:确保索引为Datetime类型
首先要把你的索引转换成datetime格式,这样才能方便地按时分秒分组:
import pandas as pd import numpy as np # 修正示例数据(替换Nan为np.nan,转换索引为datetime) df = pd.DataFrame( {'Col1': [1,5,6,np.nan,np.nan,np.nan]}, index= pd.to_datetime([ '2018-06-01 08:00:00', '2018-06-01 08:01:00', '2018-06-02 08:01:00', '2018-06-03 08:01:00', '2018-06-04 08:01:00', '2018-06-02 08:00:00' ]) )
第二步:用GroupBy + Transform填充
这是最简洁高效的方法,通过按时分秒分组,然后对每个组内的缺失值用组均值填充:
# 按时分秒分组,对Col1列应用组内均值填充缺失值 df['Col1'] = df.groupby(df.index.dt.time)['Col1'].transform( lambda x: x.fillna(x.mean()) )
为什么这个方法有效?
df.index.dt.time会提取每个索引的时分秒部分(比如08:01:00),以此作为分组依据transform方法会把每个组的计算结果(这里是组均值)映射回原数据的对应位置,保证每个位置只填充自己所在组的均值- 最终只有对应时分秒组内的NaN会被填充,不会影响其他时间的数据
验证结果
处理后的DataFrame会变成:
Col1 2018-06-01 08:00:00 1.0 2018-06-01 08:01:00 5.0 2018-06-02 08:01:00 6.0 2018-06-03 08:01:00 5.5 2018-06-04 08:01:00 5.5 2018-06-02 08:00:00 1.0
可以看到:
08:00:00组的NaN被填充为该组的均值1.008:01:00组的NaN被填充为该组的均值(5+6)/2=5.5
备选方法:遍历时分秒填充(适合理解过程)
如果你想更直观地看到每个时分秒的填充过程,可以先计算每个时分秒的均值,再逐个填充:
# 计算每个时分秒的均值,转成字典 time_means = df.groupby(df.index.dt.time)['Col1'].mean().to_dict() # 遍历每个时分秒,填充对应时间的缺失值 for time_val, mean_val in time_means.items(): df.loc[df.index.time == time_val, 'Col1'] = df.loc[df.index.time == time_val, 'Col1'].fillna(mean_val)
这个方法和上面的transform效果完全一致,只是写法更繁琐,适合小数据集或者需要调试的场景。
内容的提问来源于stack exchange,提问作者Gopal Chitalia
相关产品推荐
相关产品推荐

