首页 > 解决方案 > 以非均匀长度的间隔分割时间序列

问题描述

我有一个时间序列,中间有休息时间(没有录音的时间)。一个简化的例子是:

df = pd.DataFrame(
    np.random.rand(13), columns=["values"], 
    index=pd.date_range(start='1/1/2020 11:00:00',end='1/1/2020 23:00:00',freq='H'))
df.iloc[4:7] = np.nan
df.dropna(inplace=True)
df

                     values
2020-01-01 11:00:00 0.100339
2020-01-01 12:00:00 0.054668
2020-01-01 13:00:00 0.209965
2020-01-01 14:00:00 0.551023
2020-01-01 18:00:00 0.495879
2020-01-01 19:00:00 0.479905
2020-01-01 20:00:00 0.250568
2020-01-01 21:00:00 0.904743
2020-01-01 22:00:00 0.686085
2020-01-01 23:00:00 0.188166

现在我想将其拆分为除以一定时间跨度(例如 2 小时)的间隔。在上面的示例中,这将是:


(                       values
 2020-01-01 11:00:00  0.100339
 2020-01-01 12:00:00  0.054668
 2020-01-01 13:00:00  0.209965
 2020-01-01 14:00:00  0.551023,
                        values
 2020-01-01 18:00:00  0.495879
 2020-01-01 19:00:00  0.479905
 2020-01-01 20:00:00  0.250568
 2020-01-01 21:00:00  0.904743
 2020-01-01 22:00:00  0.686085
 2020-01-01 23:00:00  0.188166)

我有点惊讶我没有找到任何东西,因为我认为这是一个常见问题。我目前获取每个间隔的开始和结束索引的解决方案是:

def intervals(data: pd.DataFrame, delta_t: timedelta = timedelta(hours=2)):
    data = data.sort_values(by=['event_timestamp'], ignore_index=True)
    breaks = (data['event_timestamp'].diff() > delta_t).astype(bool).values

    ranges = []
    start = 0
    end = start
    for i, e in enumerate(breaks):
        if not e:
            end = i
            if i == len(breaks) - 1:
                ranges.append((start, end))
                start = i
                end = start

        elif i != 0:
            ranges.append((start, end))
            start = i
            end = start

    return ranges

有什么建议可以让我以更聪明的方式做到这一点吗?我怀疑这应该以某种方式使用groupby.

标签: pythonpandasdataframetime-seriesintervals

解决方案


@Pierre 感谢您的意见。我现在找到了一个对我来说方便的解决方案:

df['diff'] = df.index.to_series().diff()
max_gap = timedelta(hours=2)

df['gapId'] = 0
df.loc[df['diff'] >= max_gap, ['gapId']] = 1
df['gapId'] = df['gapId'].cumsum()

list(df.groupby('gapId'))

给出:

[(0,
     values                date            diff  gapId
  0     1.0 2020-01-01 11:00:00             NaT     0
  1     1.0 2020-01-01 12:00:00 0 days 01:00:00     0
  2     1.0 2020-01-01 13:00:00 0 days 01:00:00     0
  3     1.0 2020-01-01 14:00:00 0 days 01:00:00     0),
 (1,
      values                date            diff  gapId
  7      1.0 2020-01-01 18:00:00 0 days 04:00:00     1
  8      1.0 2020-01-01 19:00:00 0 days 01:00:00     1
  9      1.0 2020-01-01 20:00:00 0 days 01:00:00     1
  10     1.0 2020-01-01 21:00:00 0 days 01:00:00     1
  11     1.0 2020-01-01 22:00:00 0 days 01:00:00     1
  12     1.0 2020-01-01 23:00:00 0 days 01:00:00     1)]

推荐阅读