首页 > 解决方案 > 在日期时间索引中查找缺失时段的开始和结束日期

问题描述

我有一个巨大datetime index的,应该有 1 分钟的频率。我知道有一段时间的数据丢失。我想检测所有丢失的数据周期并找到每个数据周期的开始和结束日期。到目前为止,我想出了如何找到丢失的时间戳:

fullrange = pd.date_range(start = obs.index.min(), end = obs.index.max(), freq = "1T")
missing_dates = obs.index.difference(fullrange)

现在我不知道如何missing_dates分成几个时期并找到它们的开始和结束日期。

obs.index看起来像这样:

DatetimeIndex(['2020-05-10 09:08:00', '2020-05-10 09:09:00',
           '2020-05-10 09:10:00', '2020-05-10 09:11:00',
           '2020-05-10 09:12:00', '2020-05-10 09:13:00',
           '2020-05-10 09:14:00', '2020-05-10 09:15:00',
           '2020-05-10 09:16:00', '2020-05-10 12:24:00', # missing data
           ...
           '2020-07-09 12:35:00', '2020-07-09 12:36:00',
           '2020-07-09 12:37:00', '2020-07-09 12:38:00',
           '2020-07-09 12:39:00', '2020-07-09 12:40:00',
           '2020-07-09 12:41:00', '2020-07-09 12:42:00',
           '2020-07-09 12:43:00', '2020-08-09 13:14:00'], # missing data
          dtype='datetime64[ns]', name='timestamp', length=86617)

预期结果是缺失数据周期的列表,每个周期是一个带有 [start, end] 的列表:

[['2020-05-10 09:16:00', '2020-05-10 12:24:00'], ['2020-07-09 12:43:00', '2020-08-09 13:14:00']]

标签: pythonpandasdatetimetime-seriesmissing-data

解决方案


利用:

rng = pd.date_range('2017-04-03', periods=10, freq='T')
df = pd.DataFrame({'a': range(10)}, index=rng)  

obs = df.iloc[[0,1,2,4,5,7,8,9]]
print (obs)
                     a
2017-04-03 00:00:00  0
2017-04-03 00:01:00  1
2017-04-03 00:02:00  2
2017-04-03 00:04:00  4
2017-04-03 00:05:00  5
2017-04-03 00:07:00  7
2017-04-03 00:08:00  8
2017-04-03 00:09:00  9

首先比较所有索引值与省略的第一个值的差异:

a = obs.index[obs.index.to_series().diff().ne(pd.Timedelta(1, 'T'))][1:]

然后通过以下方式获取此值的位置Index.get_indexer

pos = obs.index.get_indexer(a)

将输出转换为字符串:

idx = obs.index.astype(str)

最后使用zip通过减去1实际值来索引先前的值list comprehension

out = [list(x) for x in zip(idx[pos-1], idx[pos])]
print (out)
[['2017-04-03 00:02:00', '2017-04-03 00:04:00'], 
 ['2017-04-03 00:05:00', '2017-04-03 00:07:00']]

推荐阅读