【问题标题】:Finding Time Slot of Dataframe according to Entry Time and Exit Time根据进入时间和退出时间查找Dataframe的时间槽
【发布时间】:2021-11-13 20:51:50
【问题描述】:

我创建了一个间隔为 30 分钟的时隙数据帧,从 2020 年 1 月 10 日到 2020 年 3 月 10 日,如下所示:

timeInterval=pd.DataFrame()
startYear = 2020
startMonth = 10
startDay = 1
endYead = 2020
endMonth = 10
endDay = 3
interval  = 30

startDate = str(datetime(startYear,startMonth,startDay).date())
endDate   = str(datetime(endYear,endMonth,endDay).date())

endDateMinus1 = str(datetime(endYear,endMonth,endDay)-timedelta(seconds=1))
timeInterval['Start']=pd.date_range(start=startDate+' 00:00:00', end=endDateMinus1,freq=str(interval)+'T')
timeInterval['End']= pd.date_range(start=startDate+' 00:'+str(interval)+':00', end=endDate+' 00:00:00',freq=str(interval)+'T')

           Start                    End
0    2020-10-01 00:00:00    2020-10-01 00:30:00
1    2020-10-01 00:30:00    2020-10-01 01:00:00
2    2020-10-01 01:00:00    2020-10-01 01:30:00
3    2020-10-01 01:30:00    2020-10-01 02:00:00
4    2020-10-01 02:00:00    2020-10-01 02:30:00
...          ...                  ...
91   2020-10-02 21:30:00    2020-10-02 22:00:00
92   2020-10-02 22:00:00    2020-10-02 22:30:00
93   2020-10-02 22:30:00    2020-10-02 23:00:00
94   2020-10-02 23:00:00    2020-10-02 23:30:00
95   2020-10-02 23:30:00    2020-10-03 00:00:00

我有一个 DataFrame df 有 100k+ 行,我需要通过它并根据它所在的时隙进行计数。示例 DataFrame 如下:

    Entry_Time            Exit_Time             Sector
0   2020-10-01 22:24:00   2020-10-01 22:50:55   North
1   2020-10-01 22:32:00   2020-10-01 22:53:00   West
2   2020-10-01 22:44:00   2020-10-01 23:01:53   Central
3   2020-10-01 22:50:55   2020-10-01 23:04:07   North
4   2020-10-01 22:53:00   2020-10-01 23:03:54   North
5   2020-10-01 23:01:53   2020-10-01 23:13:44   West
6   2020-10-01 23:04:07   2020-10-01 23:26:48   Central
7   2020-10-01 23:13:44   2020-10-01 23:28:00   Central
8   2020-10-02 15:02:00   2020-10-02 15:09:31   West
9   2020-10-02 15:09:31   2020-10-02 15:25:47   North

我需要根据timeInterval数据框找到df每一行所在的时隙。所以预期的结果可能如下所示:

    Entry_Time            Exit_Time             Sector    Timeslot
0   2020-10-01 22:24:00   2020-10-01 22:50:55   North     2020-10-01 22:00:00 - 2020-10-01 22:30:00,2020-10-01 22:30:00 - 2020-10-01 23:00:00
1   2020-10-01 22:32:00   2020-10-01 22:53:00   West      2020-10-01 22:30:00 - 2020-10-01 23:00:00
2   2020-10-01 22:44:00   2020-10-01 23:01:53   Central   2020-10-01 22:30:00 - 2020-10-01 23:00:00,2020-10-01 23:00:00 - 2020-10-01 23:30:00
3   2020-10-01 22:50:55   2020-10-01 23:04:07   North     2020-10-01 22:30:00 - 2020-10-01 23:00:00,2020-10-01 23:00:00 - 2020-10-01 23:30:00
4   2020-10-01 22:53:00   2020-10-01 23:03:54   North     2020-10-01 22:30:00 - 2020-10-01 23:00:00,2020-10-01 23:00:00 - 2020-10-01 23:30:00 
5   2020-10-01 23:01:53   2020-10-01 23:13:44   West      2020-10-01 23:00:00 - 2020-10-01 23:30:00
6   2020-10-01 23:04:07   2020-10-01 23:26:48   Central   2020-10-01 23:00:00 - 2020-10-01 23:30:00
7   2020-10-01 23:13:44   2020-10-01 23:28:00   Central   2020-10-01 23:00:00 - 2020-10-01 23:30:00
8   2020-10-02 15:02:00   2020-10-02 15:09:31   West      2020-10-02 15:00:00 - 2020-10-02 15:30:00
9   2020-10-02 15:09:31   2020-10-02 15:25:47   North     2020-10-02 15:00:00 - 2020-10-02 15:30:00

【问题讨论】:

    标签: python-3.x pandas datetime


    【解决方案1】:

    由于这些是固定间隔,您可以简单地使用 .dt accessor 分别正确地设置起始列和结束列,然后在这些范围上使用 pd.date_range:

    >>> interval = pd.Timedelta(minutes=30)
    >>> df['Entry_Time'].dt.floor(freq=interval)
    0   2020-10-01 22:00:00
    1   2020-10-01 22:30:00
    2   2020-10-01 22:30:00
    3   2020-10-01 22:30:00
    4   2020-10-01 22:30:00
    5   2020-10-01 23:00:00
    6   2020-10-01 23:00:00
    7   2020-10-01 23:00:00
    8   2020-10-02 15:00:00
    9   2020-10-02 15:00:00
    Name: Entry_Time, dtype: datetime64[ns]
    >>> bounds = pd.concat([
    ...   df['Entry_Time'].dt.floor(freq=interval),
    ...   df['Exit_Time'].dt.ceil(freq=interval)
    ... ], axis='columns')
    >>> df.join(bounds.agg(lambda s: pd.date_range(*s, freq=interval).to_list(),
    ...                    axis='columns').rename('Timeslot'))
               Entry_Time           Exit_Time   Sector                                           Timeslot
    0 2020-10-01 22:24:00 2020-10-01 22:50:55    North  [2020-10-01 22:00:00, 2020-10-01 22:30:00, 202...
    1 2020-10-01 22:32:00 2020-10-01 22:53:00     West         [2020-10-01 22:30:00, 2020-10-01 23:00:00]
    2 2020-10-01 22:44:00 2020-10-01 23:01:53  Central  [2020-10-01 22:30:00, 2020-10-01 23:00:00, 202...
    3 2020-10-01 22:50:55 2020-10-01 23:04:07    North  [2020-10-01 22:30:00, 2020-10-01 23:00:00, 202...
    4 2020-10-01 22:53:00 2020-10-01 23:03:54    North  [2020-10-01 22:30:00, 2020-10-01 23:00:00, 202...
    5 2020-10-01 23:01:53 2020-10-01 23:13:44     West         [2020-10-01 23:00:00, 2020-10-01 23:30:00]
    6 2020-10-01 23:04:07 2020-10-01 23:26:48  Central         [2020-10-01 23:00:00, 2020-10-01 23:30:00]
    7 2020-10-01 23:13:44 2020-10-01 23:28:00  Central         [2020-10-01 23:00:00, 2020-10-01 23:30:00]
    8 2020-10-02 15:02:00 2020-10-02 15:09:31     West         [2020-10-02 15:00:00, 2020-10-02 15:30:00]
    9 2020-10-02 15:09:31 2020-10-02 15:25:47    North         [2020-10-02 15:00:00, 2020-10-02 15:30:00]
    

    请注意,我假设您的列是正确的日期时间数据类型。 如果不是,请将df['Entry_Time'].dt.floor(freq=interval) 替换为pd.to_datetime(df['Entry_Time']).dt.floor(freq=interval) 并同样替换为Exit_Time

    【讨论】:

    • 谢谢,这比我使用的方法好很多。只有两件事:1-我可能没有提到它,但后来我需要每个时间段将所有列数据放在一个单独的行中,并且我打算使用explode功能。但在这种情况下,我将无法做到,不是吗? 2- 我看到这只是时隙的开始,所以我需要做一些进一步的组合来获得正确的时隙?
    • @AliSultan .explode() 可以正常工作。事实上,你只有时间段的开始/结束。
    猜你喜欢
    • 1970-01-01
    • 2013-08-16
    • 2021-06-20
    • 2018-08-28
    • 1970-01-01
    • 1970-01-01
    • 2018-04-22
    • 2019-03-19
    • 1970-01-01
    相关资源
    最近更新 更多