查找重叠的熊猫日期范围之间的差距

时间:2021-05-06 16:09:03

标签: python pandas datetimeindex

我试图找出一组日期范围与较大日期范围不重叠的差距。在下面的示例中,我想找到 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, ...]

2 个答案:

答案 0 :(得分:3)

试试:

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 使用 max 和 min 来查找每个组的开始和结束。

答案 1 :(得分:1)

您可以使用 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