【问题标题】:Finding whether there is any overlap between two date periods in DataFrame查找 DataFrame 中两个日期期间之间是否有任何重叠
【发布时间】:2022-01-09 12:30:19
【问题描述】:

我有以下pd.DataFrame

df = pd.DataFrame({'admission_timestamp': ['2021-01-17 17:45:00', '2020-03-31 23:32:00', '2020-03-27 18:20:00', '2020-04-17 18:12:00', '2020-03-19 19:12:00'], 'end_period': ['2021-01-18 17:45:00', '2020-04-01 23:32:00', '2020-03-28 18:20:00', '2020-04-18 18:12:00', '2020-03-20 19:12:00'], 'start_med': ['NaT', '2020-04-01 00:00:00', '2020-03-27 19:00:00', '2020-04-17 18:39:24', 'NaT'], 'end_med': ['NaT', '2020-04-14 21:00:00', '2020-04-05 00:00:00', '2020-05-06 22:07:29', 'NaT']})

看起来像:

   admission_timestamp  end_period           start_med            end_med 
1  2021-01-17 17:45:00  2021-01-18 17:45:00  NaT                  NaT   
2  2020-03-31 23:32:00  2020-04-01 23:32:00  2020-04-01 00:00:00  2020-04-14 21:00:00
3  2020-03-27 18:20:00  2020-03-28 18:20:00  2020-03-27 19:00:00  2020-04-05 00:00:00
4  2020-04-17 18:12:00  2020-04-18 18:12:00  2020-04-17 18:39:24  2020-05-06 22:07:29   
5  2020-03-19 19:12:00  2020-03-20 19:12:00  NaT                  NaT

我想创建一个新列 received_medidation 来说明患者是否(布尔)在 admission_timestampend_period 之间接受了药物治疗(即使只有一秒钟)。因此,布尔值应该说明admission_timestampend_period 之间是否有任何时间与start_medend_med 之间的时间重叠。 dtypes 都是 datetime64[ns]

我知道我们可以创建布尔掩码,例如

condition = (df['date'] > start_date) & (df['date'] <= end_date)

...但是我不明白这如何可能解决上述任务。任何帮助表示赞赏。

【问题讨论】:

  • 您要逐行比较?
  • @Corralien 我想创建一个新列,说明在此期间是否收到了药物。

标签: python pandas dataframe datetime


【解决方案1】:

如果保证start_med 晚于admission_timestamp,那么start_med 日期在admission_timestampend_period 之间就足够了

for col in df.columns:
    df[col] = pd.to_datetime(df[col])

df['received_medidation'] = (df['admission_timestamp'] < df['start_med']) & (df['start_med'] < df['end_period'])

但是,如果 start_med 可以在 admission_timestamp 之前,那么这意味着 'start_med' &lt; 'admission_timestamp' &lt; 'end_med' 也会创建日期的交集。然后我们使用 OR 运算符将这个案例与前一个案例包括在内:

df['received_medidation'] = (df['start_med'].between(df['admission_timestamp'], df['end_period']) |
                             df['admission_timestamp'].between(df['start_med'], df['end_med']))

注意:这里的总体假设是 admission_timestamp &lt; end_periodstart_med &lt; end_med 总是正确的,在这种情况下,上面的逻辑表达式会捕获所有相交的日期。

输出:

  admission_timestamp          end_period           start_med  \
0 2021-01-17 17:45:00 2021-01-18 17:45:00                 NaT   
1 2020-03-31 23:32:00 2020-04-01 23:32:00 2020-04-01 00:00:00   
2 2020-03-27 18:20:00 2020-03-28 18:20:00 2020-03-27 19:00:00   
3 2020-04-17 18:12:00 2020-04-18 18:12:00 2020-04-17 18:39:24   
4 2020-03-19 19:12:00 2020-03-20 19:12:00                 NaT   

              end_med  received_medidation  
0                 NaT                False  
1 2020-04-14 21:00:00                 True  
2 2020-04-05 00:00:00                 True  
3 2020-05-06 22:07:29                 True  
4                 NaT                False  

【讨论】:

    【解决方案2】:

    使用between

    df['overlaps'] = df['start_med'].between(df['admission_timestamp'], df['end_period']) \
                     | df['end_med'].between(df['admission_timestamp'], df['end_period'])
    print(df)
    
    # Output
      admission_timestamp          end_period           start_med             end_med  overlaps
    1 2021-01-17 17:45:00 2021-01-18 17:45:00                 NaT                 NaT     False
    2 2020-03-31 23:32:00 2020-04-01 23:32:00 2020-04-01 00:00:00 2020-04-14 21:00:00      True
    3 2020-03-27 18:20:00 2020-03-28 18:20:00 2020-03-27 19:00:00 2020-04-05 00:00:00      True
    4 2020-04-17 18:12:00 2020-04-18 18:12:00 2020-04-17 18:39:24 2020-05-06 22:07:29      True
    5 2020-03-19 19:12:00 2020-03-20 19:12:00                 NaT                 NaT     False
    

    【讨论】:

    • 我刚刚意识到start_med 可以出现在admission_timestamp 之前。在这种情况下,start_med 是 admission_timestamp 并且 end_med 可能是 > end_period。那我们就不能用between了,你有解决办法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多