【问题标题】:Checking if date is between multiple date ranges检查日期是否在多个日期范围之间
【发布时间】:2020-06-24 20:58:24
【问题描述】:

我有 2 个数据框:

df1 = pd.DataFrame({'name': ['Bob', 'Jenny', 'Larry', 'Sam', 'Ashley', 'John', 'Bob', 'Jenny', 'Larry' , 'Sam', 'Ashley', 'John'], 'start_time': ['2020-06-01 08:01:45', '2020-06-01 08:55:47', '2020-06- 01 09:07:00'、'2020-06-01 09:12:00'、'2020-06-01 09:12:40'、'2020-06-01 09:22:05'、'2020- 06-02 08:01:45'、'2020-06-02 08:55:47'、'2020-06-02 09:07:00'、'2020-06-02 09:12:00'、' 2020-06-02 09:12:40', '2020-06-02 09:22:05'], 'end_time':['2020-06-01 16:15:00', '2020-06-01 17:00:00'、'2020-06-01 17:05:04'、'2020-06-01 17:12:12'、'2020-06-01 17:45:00'、'2020-06 -01 19:05:00'、'2020-06-02 16:15:00'、'2020-06-02 17:00:00'、'2020-06-02 17:05:04'、'2020 -06-02 17:12:12'、'2020-06-02 17:45:00'、'2020-06-02 19:05:00']})
df2 = pd.DataFrame({'name': ['Bob', 'Bob', 'Jenny', 'Ashley', 'Bob', 'John', 'John', 'Jenny', 'Sam'], 'time': ['2020-06-01 08:07:00', '2020-06-01 08:40:47', '2020-06-01 8:50:00', '2020-06-01 10:10:30', '2020-06-01 14:12:33', '2020-06-01 14:41:33', '2020-06-01 15:12:33', '2020-06-01 18:44:33', '2020-06-01 22:12:07']})

我正在尝试检查 df2 中的给定 'time' 是否包含在具有相同名称的任何时间跨度内(即我只是想检查 Bob 在 df2 中的条目与 Bob 的 @987654325 @s 和 'end_time's 在 df1) 并在 df2 的新列中返回一个布尔值。这是我期望的输出:

df2 = pd.DataFrame({'name': ['Bob', 'Bob', 'Jenny', 'Ashley', 'Bob', 'John', 'John', 'Jenny', 'Sam'], 'time': ['2020-06-01 08:07:00', '2020-06-01 08:40:47', '2020-06-01 8:50:00', '2020-06-01 10:10:30', '2020-06-01 14:12:33', '2020-06-01 14:41:33', '2020-06-01 15:12:33', '2020-06-01 18:44:33', '2020-06-01 22:12:07'], 'legal': [True, True, False, True, True, True, True, False, False]})

我尝试过使用 if 函数,但我不断收到 ValueError: Can only compare same-labeled Series objects。有什么建议吗?

【问题讨论】:

    标签: python pandas dataframe date


    【解决方案1】:

    您可以通过左连接、比较然后聚合取“合法”的最大值来做到这一点:

    df3 = df2.merge(df1, on='name', how='left')
    
    df3['legal'] = (df3['time'] >= df3['start_time']) & (df3['time'] <= df3['end_time'])
    
    print(df3[['name', 'time', 'legal']].groupby(['name', 'time']).max().reset_index())
    

    打印

         name                 time  legal
    0  Ashley  2020-06-01 10:10:30   True
    1     Bob  2020-06-01 08:07:00   True
    2     Bob  2020-06-01 08:40:47   True
    3     Bob  2020-06-01 14:12:33   True
    4   Jenny  2020-06-01 18:44:33  False
    5   Jenny   2020-06-01 8:50:00  False
    6    John  2020-06-01 14:41:33   True
    7    John  2020-06-01 15:12:33   True
    8     Sam  2020-06-01 22:12:07  False
    

    注意:比较字符串时,日期时间格式必须一致。

    【讨论】:

    • 这个:x.time &gt;= x.start_time and x.time &lt;= x.end_time可以写成x.start_time &lt;= x.time &lt;= x.end_time
    • 你说得对,用@Ben.T 的建议更新了答案
    【解决方案2】:
    res = df2.merge(df1, on='name', how='left').drop_duplicates( subset='time', keep='first').sort_values(by='name')
    res['legal']=res['time'].between(res['start_time'],res['end_time'])
    res.drop(columns=['start_time','end_time'], inplace=True)
    

    打印(分辨率)

         name                 time  legal
    6   Ashley  2020-06-01 10:10:30   True
    0      Bob  2020-06-01 08:07:00   True
    2      Bob  2020-06-01 08:40:47   True
    8      Bob  2020-06-01 14:12:33   True
    4    Jenny   2020-06-01 8:50:00  False
    14   Jenny  2020-06-01 18:44:33  False
    10    John  2020-06-01 14:41:33   True
    12    John  2020-06-01 15:12:33   True
    16     Sam  2020-06-01 22:12:07  False
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-27
      • 1970-01-01
      • 2017-01-28
      相关资源
      最近更新 更多