查找重叠的 pandas 个数据范围之间的间隙

Find gaps between pandas dateranges that overlap

我试图找到一组日期范围不与较大日期范围重叠的间隙。在下面的示例中,我想找到 daterange_1daterange_3 不重叠 big_daterange.

的每个间隙

目前我已经走到这一步了,但我仍然坚持从 diff 中提取差距,如果这是解决这个问题的最佳方法的话。

import pandas as pd

daterange_1 = pd.date_range("2009-01-01", "2010-01-01")
daterange_2 = pd.date_range("2012-01-01", "2014-01-01")
daterange_3 = pd.date_range("2016-01-01", "2019-01-01")

big_daterange = pd.date_range("2001-01-01", "2021-01-01")

combined = daterange_1.union(daterange_2).union(daterange_3)

# Get the dates in big_daterange that aren't in combined
diff = big_daterange.difference(combined)

我最感兴趣的是如何提取间隙(其中间隙是连续日期时间的日期范围)并像这样创建它们的列表:

gaps = [gap_daterange_1, gap_daterange_2, ...]

您可以使用reindex方法。
到处都是 NaT,那是因为 dtiX 中缺少日期:

dti1 = pd.date_range("2009-01-01", "2010-01-01")
dti2 = pd.date_range("2012-01-01", "2014-01-01")
dti3 = pd.date_range("2016-01-01", "2019-01-01")

dti = pd.date_range("2001-01-01", "2021-01-01")

sr = pd.concat([dti1.to_series(), dti2.to_series(), dti3.to_series()]) \
       .sort_index().reindex(dti)

sr = sr[sr.isnull()]
>>> sr.index
DatetimeIndex(['2001-01-01', '2001-01-02', '2001-01-03', '2001-01-04',
               '2001-01-05', '2001-01-06', '2001-01-07', '2001-01-08',
               '2001-01-09', '2001-01-10',
               ...
               '2020-12-23', '2020-12-24', '2020-12-25', '2020-12-26',
               '2020-12-27', '2020-12-28', '2020-12-29', '2020-12-30',
               '2020-12-31', '2021-01-01'],
              dtype='datetime64[ns]', length=5111, freq=None)

通过创建非连续天的组来查找差距:

sr = sr.index.to_series()
groups = sr.sub(sr.shift()) \
           .fillna(pd.Timedelta(days=1)) \
           .ne(pd.Timedelta(days=1)) \
           .cumsum()
gaps = sr.groupby(groups).agg(['min','max'])
>>> gaps
         min        max
0 2001-01-01 2008-12-31
1 2010-01-02 2011-12-31
2 2014-01-02 2015-12-31
3 2019-01-02 2021-01-01

尝试:

s = diff.to_series()
grp = s.diff().ne(pd.Timedelta(days=1)).cumsum()
gaps = s.groupby(grp).agg(['min','max'])
gaps

输出:

         min        max
1 2001-01-01 2008-12-31
2 2010-01-02 2011-12-31
3 2014-01-02 2015-12-31
4 2019-01-02 2021-01-01

详情:

首先,使用 to_series.
将 DateTimeIndex 转换为 pd.Series 接下来使用 diff 求出两个连续值之间的差值。 如果 diff 大于一天,则将此记录标记为 True。使用 cumsum 在 True 记录之间创建记录组。最后,groupby grp an 使用 max 和 min 来找到每个组的开始和结束。