填补时间序列 pandas 数据帧中的空白
Fill Gaps in time series pandas dataframe
我有一个 pandas 数据帧,在时间序列中存在间隙。
看起来像下面这样:
示例输入
--------------------------------------
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
期望的输出
--------------------------------------------
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
我试过的是:
'# 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')
但是,如果我这样做,它还会在原始数据框中不存在的日期上重新采样并生成新的时间戳。在上面的示例中,它还会为 2021-02-08
按分钟生成时间戳
我怎样才能避免这种情况?
此外,有没有更好的方法来避免整个时间重新采样。
df_process_out = df_process.resample(rule='1T').ffill()
这会生成从 00:00 到 24:00 的时间戳,在下一行代码中我必须再次过滤掉大部分时间戳。
好像效率不高。
任何 help/guidance 将不胜感激
谢谢
编辑:
根据要求,小样本集
df_in: 输入数据
df_out_error: 输出数据错误
df_out_OK:输出数据应该是什么样子
在下面的 ColabNotebook 中我准备了一个小样本。
https://colab.research.google.com/drive/1Fps2obTv1YPDpTzXTo7ivLI5njoI-y4n?usp=sharing
请注意,这只是数据的一小部分。
我正在尝试清理多年的结构化数据,并像这样显示缺少的分钟时间戳。
您可以结合使用 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
说明
1。仅在有限的时间段内重新采样
"Furthermore is there a better way to avoid resampling over the whole time. This generates timestamps from 00:00 to 24:00 and in the next line of code I have to filter most timestamps out again. Doesn't seem efficient."
与上述解决方案一样,您可以使用规则 = 1Min
重新采样,然后 ffill
(或任何其他类型的填充)。这确保您不会从 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()
注意给定日期的开始 (09:30:00) 和结束 (16:00:00) 时间戳。
2。仅对现有日期应用重采样
"In the example above it would also generate timestamps on a minute basis for 2021-02-08. How can I avoid this?"
与上述解决方案一样,您可以分别对日期组应用重采样方法。在这种情况下,我在将日期与时间戳分开后使用 lambda 函数应用该方法。因此,重采样仅发生在 存在于数据集中的日期
df_new.Timestamp.dt.date.unique()
array([datetime.date(2021, 2, 7), datetime.date(2021, 2, 9)], dtype=object)
注意,输出仅包含原始数据集中的 2 个唯一日期。
我有一个 pandas 数据帧,在时间序列中存在间隙。
看起来像下面这样:
示例输入
--------------------------------------
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
期望的输出
--------------------------------------------
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
我试过的是:
'# 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')
但是,如果我这样做,它还会在原始数据框中不存在的日期上重新采样并生成新的时间戳。在上面的示例中,它还会为 2021-02-08
按分钟生成时间戳我怎样才能避免这种情况?
此外,有没有更好的方法来避免整个时间重新采样。
df_process_out = df_process.resample(rule='1T').ffill()
这会生成从 00:00 到 24:00 的时间戳,在下一行代码中我必须再次过滤掉大部分时间戳。 好像效率不高。
任何 help/guidance 将不胜感激
谢谢
编辑:
根据要求,小样本集
df_in: 输入数据
df_out_error: 输出数据错误
df_out_OK:输出数据应该是什么样子
在下面的 ColabNotebook 中我准备了一个小样本。
https://colab.research.google.com/drive/1Fps2obTv1YPDpTzXTo7ivLI5njoI-y4n?usp=sharing
请注意,这只是数据的一小部分。 我正在尝试清理多年的结构化数据,并像这样显示缺少的分钟时间戳。
您可以结合使用 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
说明
1。仅在有限的时间段内重新采样
"Furthermore is there a better way to avoid resampling over the whole time. This generates timestamps from 00:00 to 24:00 and in the next line of code I have to filter most timestamps out again. Doesn't seem efficient."
与上述解决方案一样,您可以使用规则 = 1Min
重新采样,然后 ffill
(或任何其他类型的填充)。这确保您不会从 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()
注意给定日期的开始 (09:30:00) 和结束 (16:00:00) 时间戳。
2。仅对现有日期应用重采样
"In the example above it would also generate timestamps on a minute basis for 2021-02-08. How can I avoid this?"
与上述解决方案一样,您可以分别对日期组应用重采样方法。在这种情况下,我在将日期与时间戳分开后使用 lambda 函数应用该方法。因此,重采样仅发生在 存在于数据集中的日期
df_new.Timestamp.dt.date.unique()
array([datetime.date(2021, 2, 7), datetime.date(2021, 2, 9)], dtype=object)
注意,输出仅包含原始数据集中的 2 个唯一日期。