【问题标题】:pandas: Issue with filtering datetime values based on multiple columnspandas:基于多列过滤日期时间值的问题
【发布时间】:2020-07-10 16:58:24
【问题描述】:

在给定以下数据帧的情况下,我面临与过滤掉在特定时间间隔内活动的事件相关的任何问题,即 7 到 9:

EventId             StartTime                       EndTime            
18   2013-04-11 16:33:11.735342100   2013-04-11 17:16:47.976164100  
19   2013-04-10 16:33:46.575337300   2013-04-11 18:10:08.428443900  
20   2013-04-10 17:17:04.033083300   2013-04-11 18:10:13.907757900  
21   2013-04-11 00:10:24.293352100   2013-04-11 18:45:17.754240800  
23   2013-04-11 01:11:20.278558900   2013-04-11 18:45:00.435247300  
25   2013-04-15 09:42:22.549026700   2013-04-15 23:54:33.389964300  
26   2013-04-16 07:42:24.588807700   2013-04-16 17:42:41.077751300  
28   2013-04-19 16:51:22.699240800   2013-04-19 18:39:03.167468100  
31   2013-04-19 18:30:56.891621300   2013-04-19 19:42:50.418640200  
17   2013-04-20 16:07:07.327879000   2013-04-20 22:17:17.783053600  

我想获取那些在上午 7 点到 9 点期间活动的事件,包括 8 点,并在将小时数提取为单独的列之后使用以下查询。

df['StartTime']=pd.to_datetime(df['StartTime'])

df['EndTime']=pd.to_datetime(df['EndTime'])

df['StartHr']=df['StartTime'].dt.hour
df['EndHr']=df['EndTime'].dt.hour
df[((df['StartHr']<=7)| (df['StartHr']==8)) & ((df['EndHr']==8)|(df['EndHr']>=9))]

它按预期工作,但鉴于数据集无法获得某些结果,例如事件 ID 20

            20   2018-05-10 17:17:04.033083300   2018-05-11 18:10:13.907757900  

因为这个活动在第二天7-9的时间间隔内有效,但我无法得到它。 id 2621 同样适用于解决此问题的任何帮助。如何比较 pandas 中的日期时间值。

【问题讨论】:

    标签: python pandas dataframe datetime


    【解决方案1】:

    首先你可以有更简单的条件,即:

    df[((df['StartHr']<=8)) & ((df['EndHr']>=8))]
    

    我想不出比将结束时间和开始时间之间的差与 79200 秒进行比较更简单的方法了,这对应于事件从上午 9 点开始到上午 7 点结束之间的秒数早上之后,即您的案件的限制持续时间(22 小时)。

    我的代码如下所示:

    limit_delta = 79200
    test_df['diff'] = (test_df['EndTime'] - test_df['StartTime']).map(lambda td : td.total_seconds())
    test_df[(((test_df['StartHr']<=8) & (test_df['EndHr']>=8)) | (test_df['diff'] <= limit_delta))] 
    

    如果这解决了您的问题,请告诉我。

    【讨论】:

    • 实际上错过了事件 20,该事件在 7-9 范围内处于活动状态,并且从前一天开始。
    • 是的,我应该做一个或而不是一个和。我正在编辑我的答案。测试了它,现在它可以工作了
    • 另一种尝试。
    • 我认为您的解决方案仅替换了小时的测试,您是否过滤掉了 20 索引?
    【解决方案2】:

    我试了一下。

    df=pd.DataFrame({'EventId':[18,19,20,21], 'startTime':['2013-04-11 07:33:11.735342100','2013-04-10 16:33:46.575337300','2013-04-10 08:17:04.033083300','2013-04-11 00:10:24.293352100'],'EndTime':['2013-04-11 08:16:47.976164100','2013-04-11 18:10:08.428443900','2013-04-11 09:10:13.907757900','2013-04-11 18:45:17.754240800']})
    

    将日期强制转换为日期时间

    df['startTime']=pd.to_datetime(df['startTime'])
    df['EndTime']=pd.to_datetime(df['EndTime'])
    df.set_index(['startTime'], inplace=True)
    

    使用.between_time设置每个时间纪元,开始和结束以索引并提取合适的时间

    df['StartHr']=df.index.time
    a=df.iloc[:,:1].between_time('07:00:00', '09:00:00')
    df.reset_index(inplace=True)
    a.reset_index(inplace=True)
    
    df.set_index(['EndTime'], inplace=True)
    df['EndHr']=df.index.time
    b=df.iloc[:,:-2].between_time('07:00:00', '09:00:00')
    b.reset_index(inplace=True)
    

    合并两个结果

    df2=pd.merge(a, b, on='EventId')
    

    【讨论】:

      猜你喜欢
      • 2016-12-18
      • 2020-03-22
      • 2012-09-30
      • 2019-11-17
      • 2014-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多