【问题标题】:Pandas, how to check which date_range values are in pd.Interval column's time rangePandas,如何检查哪些 date_range 值在 pd.Interval 列的时间范围内
【发布时间】:2021-12-22 00:17:13
【问题描述】:

我有一个表示(多个)小时间隔的数据框:

import pandas as pd
df = pd.DataFrame(
    {
        'reserved': [
                        pd.Interval(pd.Timestamp(2011,11,9,8), pd.Timestamp(2011,11,9,12), closed='left'),
                        pd.Interval(pd.Timestamp(2011,11,9,13), pd.Timestamp(2011,11,9,21), closed='left')
                    ],
        'value': [1, 2]
})

|    | reserved                                   |   value |
|---:|:-------------------------------------------|--------:|
|  0 | [2011-11-09 08:00:00, 2011-11-09 12:00:00) |       1 |
|  1 | [2011-11-09 13:00:00, 2011-11-09 21:00:00) |       2 |

我必须找出从 07:00 到 23:00 没有保留的时间。 像这样的:

working_hours = pd.date_range('2021-11-09 07', '2021-11-09 23', freq='1H')

DatetimeIndex(['2021-11-09 07:00:00', '2021-11-09 08:00:00',
               '2021-11-09 09:00:00', '2021-11-09 10:00:00',
               '2021-11-09 11:00:00', '2021-11-09 12:00:00',
               '2021-11-09 13:00:00', '2021-11-09 14:00:00',
               '2021-11-09 15:00:00', '2021-11-09 16:00:00',
               '2021-11-09 17:00:00', '2021-11-09 18:00:00',
               '2021-11-09 19:00:00', '2021-11-09 20:00:00',
               '2021-11-09 21:00:00', '2021-11-09 22:00:00',
               '2021-11-09 23:00:00'],
              dtype='datetime64[ns]', freq='H')

哪个 working_hours 不是 df.reserved 间隔的一部分? 在上面的例子中,我们可以看到2021-11-09 07:00:00没有保留,2021-11-09 12:00:00没有保留,还有小时2011-11-09 21:00:00 - 2011-11-09 22:00:00

我希望我能做这样的事情:

pd.Timestamp(2021,11,9,8) in df.reserved

但这总是返回False

我需要的是:working_hours not in df.reserved 以获得:

2021-11-09 07:00:00
2021-11-09 12:00:00
2011-11-09 21:00:00
2011-11-09 22:00:00

怎么做?

【问题讨论】:

标签: python pandas time-series intervals between


【解决方案1】:

对位置使用Index.get_indexer,如果没有返回匹配-1,那么可以过滤working_hours

i = pd.IntervalIndex(df.reserved)
s = pd.Series(working_hours[i.get_indexer(working_hours) == -1])
print (s)
0   2011-11-09 07:00:00
1   2011-11-09 12:00:00
2   2011-11-09 21:00:00
3   2011-11-09 22:00:00
4   2011-11-09 23:00:00
dtype: datetime64[ns]

Index.map 中使用IntervalIndex.contains 并通过boolean indexing 过滤range

working_hours = pd.date_range(pd.Timestamp(2011,11,9,7), 
                              pd.Timestamp(2011,11,9,23), freq='1H')

i = pd.IntervalIndex(df.reserved)
m = (working_hours.map(lambda x: not i.contains(x).any()))

s = working_hours.to_series()[m].reset_index(drop=True)
print (s)
0   2011-11-09 07:00:00
1   2011-11-09 12:00:00
2   2011-11-09 21:00:00
3   2011-11-09 22:00:00
4   2011-11-09 23:00:00
dtype: datetime64[ns]

【讨论】:

  • 它不工作。 :( working_hours = pd.date_range('2021-11-09 07', '2021-11-09 23', freq='1H') i = IntervalIndex([[2021-11-11 07:00:00, 2021 -11-11 09:00:00), [2021-11-11 09:00:00, 2021-11-11 11:00:00), [2021-11-11 11:00:00, 2021-11 -11 12:30:00), [2021-11-11 13:00:00, 2021-11-11 15:00:00), [2021-11-11 15:00:00, 2021-11-11 18:00:00), [2021-11-11 18:00:00, 2021-11-11 19:00:00), [2021-11-11 19:00:00, 2021-11-11 21: 00:00), [2021-11-11 21:00:00, 2021-11-11 23:00:00)], closed='left', name='reserved', dtype='interval[datetime64[ns ]]')
  • i.contains(pd.Timestamp(2011,11,9,9)) array([False, False, False, False, False, False, False, False]) 总是得到错误两种方法。熊猫是 1.1.3
  • 看起来我的“i”变量包含错误的区间列表。
  • @user3225309 我有同样的问题,解决方案是使用working_hours = pd.date_range(pd.Timestamp(2011,11,9,7), pd.Timestamp(2011,11,9,23), freq='1H') 而不是working_hours = pd.date_range('2021-11-09 07', '2021-11-09 23', freq='1H')
  • @jezrael,什么是 nit 想法的原因,但我猜是一些错误,pandas 中的间隔仍然是新的,所以预计会有错误。
猜你喜欢
  • 2017-11-09
  • 1970-01-01
  • 2021-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多