【问题标题】:Filling in missing hourly data in Pandas在 Pandas 中填写缺失的每小时数据
【发布时间】:2021-04-27 02:21:20
【问题描述】:

我有一个数据框,其中包含具有每小时测量值的时间序列,其结构如下:nametimeoutput。对于每个 name,测量值来自或多或少相同的时间段。我正在尝试填写缺失值,以便每天所有 24 小时都出现在 time 列中。

所以我期待这样的表格:

 name  time                   output 
 x     2018-02-22 00:00:00    100 
       ...                    
 x     2018-02-22 23:00:00    200 
 x     2018-02-24 00:00:00    300 
       ...                    
 x     2018-02-24 23:00:00    300 
 y     2018-02-22 00:00:00    100 
       ...                   
 y     2018-02-22 23:00:00    200 
 y     2018-02-25 00:00:00    300 
       ...                         
 y     2018-02-25 23:00:00    300

为此,我按 name 分组,然后尝试应用一个自定义函数,在相应的数据框中添加缺少的时间戳。

def add_missing_hours(df):
    start_date = df.time.iloc[0].date()
    end_date = df.time.iloc[-1].date()
    dates_range = pd.date_range(start_date, end_date, freq = '1H')
    new_dates = set(dates_range) - set(df.time)
    name = df["name"].iloc[0]
    df = df.append(pd.DataFrame({'GSRN':[name]*len(new_dates), 'time': new_dates}))
    return df

由于某种原因,我在创建 DataFrame 时删除了 name 列,但我不明白为什么。有谁知道为什么或更好地了解如何填写缺少的时间戳?

编辑 1:

这与 [此处的问题][1] 不同,因为他们不需要每天 24 个值 - 在下午 2 点到 10 点之间重新采样只会给出两者之间的值。

编辑 2:

我找到了一个(不是很好)解决方案,方法是创建一个包含所有名称-时间戳对的多索引并与表相结合。以下代码供任何感兴趣但仍对更好的解决方案感兴趣的人使用:

start_date = datetime.datetime.combine(df.time.min().date(),datetime.time(0, 0))
end_date = datetime.datetime.combine(df.time.max().date(),datetime.time(23, 0))
new_idx = pd.date_range(start_date, end_date, freq = '1H')

mux = pd.MultiIndex.from_product([df['name'].unique(),new_idx], names=('name','time'))
df_complete = pd.DataFrame(index=mux).reset_index().combine_first(df)
df_complete = df_complete.groupby(["name",df_complete.time.dt.date]).filter(lambda g: (g["output"].count() == 0))

最后一行删除了初始数据框中特定名称完全缺失的所有日期。

【问题讨论】:

  • 这能回答你的问题吗? Fill in missing hours in a pandas dataframe
  • 谢谢,但不完全是,因为重采样不一定能提供完整的 24 小时;例如,如果一天的第一次测量是在下午 2 点,重新采样将忽略一天的第一部分。

标签: python pandas dataframe time-series missing-data


【解决方案1】:

尝试:

第一次创建从最小日期到最大日期的数据框,以小时为间隔。然后将它们连接在一起。

df.time = pd.to_datetime(df.time)
min_date = df.time.min()
max_date = df.time.max()
dates_range = pd.date_range(min_date, max_date, freq = '1H')
df.set_index('time', inplace=True)
df3=pd.DataFrame(dates_range).set_index(0)
df4 = df3.join(df)

df4:

                   name output
2018-02-22 00:00:00 x   100.0
2018-02-22 00:00:00 y   100.0
2018-02-22 01:00:00 NaN NaN
2018-02-22 02:00:00 NaN NaN
2018-02-22 03:00:00 NaN NaN
... ... ...
2018-02-25 19:00:00 NaN NaN
2018-02-25 20:00:00 NaN NaN
2018-02-25 21:00:00 NaN NaN
2018-02-25 22:00:00 NaN NaN
2018-02-25 23:00:00 y   300.0
98 rows × 2 columns

【讨论】:

  • 感谢您的回答!这没有名称、时间戳和输出之间的对应关系 - 名称列不应为空,因为我正在填写特定名称的缺失值。
  • @user88120:使用df3.join(df)
猜你喜欢
  • 1970-01-01
  • 2018-05-02
  • 1970-01-01
  • 2021-07-18
  • 2021-06-17
  • 2022-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多