填补时间序列 pandas 数据框中的空白

Chr*_*uer 4 python datetime time-series pandas pandas-resample

我有一个带有时间序列间隙的熊猫数据框。
它看起来像下面这样:

输入示例

--------------------------------------
     Timestamp        Close
 2021-02-07 09:30:00  124.624 
 2021-02-07 09:31:00  124.617
 2021-02-07 10:04:00  123.946
 2021-02-07 16:00:00  123.300
 2021-02-09 09:04:00  125.746
 2021-02-09 09:05:00  125.646
 2021-02-09 15:58:00  125.235
 2021-02-09 15:59:00  126.987
 2021-02-09 16:00:00  127.124 
Run Code Online (Sandbox Code Playgroud)

所需输出

--------------------------------------------
     Timestamp        Close
 2021-02-07 09:30:00  124.624 
 2021-02-07 09:31:00  124.617
 2021-02-07 09:32:00  124.617
 2021-02-07 09:33:00  124.617
   'Insert a line for each minute up to the next available
   timestamp with the Close value form the last available timestamp'
 2021-02-07 10:03:00  124.617 
 2021-02-07 10:04:00  123.946
 2021-02-07 16:00:00  123.300
   'I dont want lines inserted here. As this date is not
   present in the original dataset (could be a non trading
   day so I dont want to fill this gap)'
 2021-02-09 09:04:00  125.746
 2021-02-09 09:05:00  125.646
 2021-02-09 15:58:00  125.235
   'Fill the gaps here again but only between 09:30 and 16:00 time'
 2021-02-09 15:59:00  126.987
 2021-02-09 16:00:00  127.124 
Run Code Online (Sandbox Code Playgroud)

我尝试过的是:

'# set the index column'
df_process.set_index('Exchange DateTime', inplace=True)

'# resample and forward fill the gaps'
df_process_out = df_process.resample(rule='1T').ffill()

'# filter and return only timestamps between 09:30 and 16:00'
df_process_out = df_process_out.between_time(start_time='09:30:00', end_time='16:00:00')

Run Code Online (Sandbox Code Playgroud)

但是,如果我这样做,它还会重新采样并生成原始数据框中不存在的日期的新时间戳。在上面的示例中,它还会生成2021-02-08每分钟的时间戳

我怎样才能避免这种情况?

此外,有没有更好的方法来避免在整个时间内重新采样。

df_process_out = df_process.resample(rule='1T').ffill()
Run Code Online (Sandbox Code Playgroud)

这会生成从 00:00 到 24:00 的时间戳,在下一行代码中我必须再次过滤掉大多数时间戳。看起来效率不高。

任何帮助/指导将不胜感激,
谢谢


编辑:
根据要求提供一个小样本集

df_in:输入数据
df_out_error:错误的输出数据
df_out_OK:输出数据应该是什么样子

在下面的 ColabNotebook 中我准备了一个小样本。

https://colab.research.google.com/drive/1Fps2obTv1YPDpTzXTo7ivLI5njoI-y4n?usp=sharing

请注意,这只是数据的一小部分。我正在尝试清理多年来的结构化数据并显示丢失的分钟时间戳,如下所示。

Aks*_*gal 6

df.groupby()您可以通过(超过日期)和使用重采样的组合来实现您所需要的rule = "1Min"。尝试这个 -

df_new = (df.assign(date=df.Timestamp.dt.date)   #create new col 'date' from the timestamp
            .set_index('Timestamp')              #set timestamp as index
            .groupby('date')                     #groupby for each date
            .apply(lambda x: x.resample('1Min')  #apply resampling for 1 minute from start time to end time for that date
                   .ffill())                     #ffill values
            .reset_index('date', drop=True)      #drop index 'date' that was created by groupby
            .drop('date',1)                      #drop 'date' column created before
            .reset_index()                       #reset index to get back original 2 cols
         )

df_new
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


解释

1. 仅在有限时间内重新采样

“此外,有没有更好的方法来避免在整个时间内重新采样。这会生成从 00:00 到 24:00 的时间戳,在下一行代码中,我必须再次过滤掉大多数时间戳。这似乎效率不高。”

与上述解决方案一样,您可以重新采样,然后ffill使用rule =(或任何其他类型的填充)1Min。这可确保您不会从 00:00 到 24:00 进行重新采样,而仅从数据中可用的开始到结束时间戳进行重新采样。为了证明,我将其应用于数据中的单个日期 -

#filtering for a single day
ddd = df[df['date']==df.date.unique()[0]]

#applying resampling on that given day
ddd.set_index('Timestamp').resample('1Min').ffill()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

请注意给定日期的开始 (09:30:00) 和结束 (16:00:00) 时间戳。

2. 仅对现有日期应用重新采样

“在上面的示例中,它还会生成 2021 年 2 月 8 日每分钟的时间戳。我怎样才能避免这种情况?”

如上述解决方案所示,您可以单独对日期组应用重采样方法。在本例中,我在从时间戳中分离出日期后,使用 lambda 函数应用该方法。因此,仅对数据集中存在的日期进行重新采样

df_new.Timestamp.dt.date.unique()
Run Code Online (Sandbox Code Playgroud)
array([datetime.date(2021, 2, 7), datetime.date(2021, 2, 9)], dtype=object)
Run Code Online (Sandbox Code Playgroud)

请注意,输出仅包含原始数据集中的 2 个唯一日期。