如何在Pandas中按日期时间用前一天数据填充缺失值及解决NaN问题
Pandas补全15分钟时间间隔缺失值及填充问题
我在使用Pandas处理15分钟间隔的时间序列数据时,遇到了缺失行补全和填充的问题,尝试了几种方法都没能得到预期结果,具体情况如下:
输入数据
存在部分缺失的15分钟时间间隔数据:
Date_time,current_demand,Temp_Mean,humidity_Mean 2018-05-01 00:00,15951.0,300.904267,49.600000 2018-05-01 00:15,16075.0,300.904267,49.600000 2018-05-01 00:30,15977.0,300.904267,49.600000 2018-05-01 00:45,15945.0,300.837600,50.333333 2018-05-01 01:00,15868.0,298.889333,59.133333 2018-05-01 01:15,15583.0,298.889333,59.133333 2018-05-01 01:30,15470.0,298.756000,59.800000 2018-05-01 01:45,15301.0,298.756000,59.800000 2018-05-01 02:15,14946.0,298.756000,59.800000 2018-05-01 02:30,14736.0,298.756000,59.800000 2018-05-01 02:45,14630.0,298.502333,59.000000 2018-05-01 03:15,14350.0,298.502333,59.000000
我尝试的脚本
import pandas as pd import numpy as np df = pd.read_csv(r'submission.csv', index_col=[1], parse_dates=[1], dayfirst=True) df['Date_time'] = pd.to_datetime(df['Date_time']).dt.time start = pd.to_datetime(str(df['Date_time'].min())) end = pd.to_datetime(str(df['Date_time'].max())) dates = pd.date_range(start=start, end=end, freq='15Min').time df1 = pd.pivot_table(df, "current_demand", "Temp_Mean", "humidity_Mean").stack(dropna=False).reset_index(name="current_demand") df1.loc[df1['current_demand'].isnull(), "Temp_Mean", "Temp_Mean" , "humidity_Mean"] = np.nan
预期输出
补全15分钟时间间隔,缺失行的值用前一天数据填充(示例中暂时用0占位,实际需替换为前一天对应时间点的数据):
Date_time,current_demand,Temp_Mean,humidity_Mean 2018-05-01 00:00,15951.0,300.904267,49.600000 2018-05-01 00:15,16075.0,300.904267,49.600000 2018-05-01 00:30,15977.0,300.904267,49.600000 2018-05-01 00:45,15945.0,300.837600,50.333333 2018-05-01 01:00,15868.0,298.889333,59.133333 2018-05-01 01:15,15583.0,298.889333,59.133333 2018-05-01 01:30,15470.0,298.756000,59.800000 2018-05-01 01:45,15301.0,298.756000,59.800000 2018-05-01 02:00,0,0,0 2018-05-01 02:15,14946.0,298.756000,59.800000 2018-05-01 02:30,14736.0,298.756000,59.800000 2018-05-01 02:45,14630.0,298.502333,59.000000 2018-05-01 03:00,0,0,0 2018-05-01 03:15,14350.0,298.502333,59.000000
补充尝试的问题
我改用以下代码后,结果全为NaN,请问原因是什么?
df = df.set_index(['Date_time']).asfreq('15T').ffill() # df = df.set_index('Date_time').resample('15T').ffill() #效果相同 # df = df.asfreq('15T').ffill() df = df.asfreq('15T').fillna(df.shift(1, freq='d'))
得到的结果:
current_demand,Temp_Mean,humidity_Mean Date_time 2018-05-01 00:00:00,NaN,NaN,NaN 2018-05-01 00:15:00,NaN,NaN,NaN 2018-05-01 00:30:00,NaN,NaN,NaN 2018-05-01 00:45:00,NaN,NaN,NaN 2018-05-01 01:00:00,NaN,NaN,NaN
问题分析与解决方案
先聊聊你之前代码里踩的几个坑:
第一个脚本的问题:
- 你把
Date_time转成了dt.time,这直接丢掉了日期信息!后续生成的时间序列只有时分秒,没法和原数据的日期对应,自然补不全缺失的时间点。 - 用
pivot_table完全走错了方向,这个工具是用来做数据透视的,根本不是用来补全时间序列的。
- 你把
补充尝试的问题:
- 读取数据时你已经把
Date_time设为索引了(index_col=[1]),后面又重复set_index(['Date_time']),这会导致索引混乱,因为此时Date_time已经不是普通列了。 - 用
df.shift(1, freq='d')填充时,你的示例数据只有2018-05-01一天的记录,哪来的前一天数据?填充后全是NaN也就不奇怪了。
- 读取数据时你已经把
正确的解决方案
假设你的数据集包含多天记录(如果只有一天,前一天数据不存在,就用你示例里的0或者其他方式填充),完整代码如下:
import pandas as pd import numpy as np # 1. 读取数据:指定Date_time为datetime类型,先不设置索引 df = pd.read_csv('submission.csv', parse_dates=['Date_time'], dayfirst=True) # 2. 将Date_time设为索引,方便后续时间序列操作 df = df.set_index('Date_time') # 3. 生成完整的15分钟时间序列:从数据最早时间到最晚时间 full_time_index = pd.date_range(start=df.index.min(), end=df.index.max(), freq='15T') # 4. 重新索引,补全缺失的时间点,缺失值会自动设为NaN df_full = df.reindex(full_time_index) # 5. 填充缺失值:用前一天同一时间的数据填充(一天有96个15分钟间隔,所以shift(96)) df_full = df_full.fillna(df_full.shift(96)) # 对于没有前一天数据的情况(比如第一天的缺失值),用0填充(可根据需求替换成其他值) df_full = df_full.fillna(0) # 可选:重置索引,把Date_time变回普通列 df_full = df_full.reset_index().rename(columns={'index': 'Date_time'}) print(df_full)
如果只有单天数据的情况:
如果你的数据只有一天,没有前一天的记录,直接用0填充缺失值即可:
df_full = df.reindex(full_time_index).fillna(0).reset_index().rename(columns={'index': 'Date_time'})
这样就能得到你想要的预期输出啦!
内容的提问来源于stack exchange,提问作者user8866270
相关产品推荐
相关产品推荐

