сравните два столбца даты — проверьте, попадают ли они в диапазон — возьмите значение из 3-го столбца

#python #pandas

#python #панды

Вопрос:

Я работаю над вопросом о том, были ли получены результаты тестирования пациентов между минус 1 и 3 днями после поступления в больницу. Если это так, я хочу узнать, в какой отдел они были допущены в первую очередь.

Сложность заключается в том, что пациенты проходят многократное тестирование во время приема, а также повторно госпитализируются в короткие сроки. Тестирование 3 раза в неделю не является редкостью. Однако тесты без допуска также возможны. Я хочу убедиться, что получаю отдел приема, который связан с результатом теста и его датой.

Данные поступают из двух разных таблиц, объединенных (по техническим причинам / из-за другого источника данных) с использованием python. Я выполнил левое (внешнее) объединение этих dfs на выводе, поэтому окончательный df находится в длинном формате.

Например

 pin= [1522, 1522, 3830] 

date_rslt = ['2018-04-18', '2018-04-18', '2018-04-09'] 

date_admis = ['2017-12-14', '2018-04-17', '2018-04-08'] 
dept = ['ER', 'INT', 'ER']

df = pd.DataFrame(list(zip(pin, date_rslt, date_admis, dept)), 
               columns =['pin', 'date_rslt', 'date_admis', 'dept']) 
  

Вопросы:

  • следующий код выдает мне эту ошибку, но я не вижу, что не так с кодом. Если это разрешено, будет ли это работать нормально?
  • Есть предложения по улучшению этого кода?

ValueError: значение истинности ряда неоднозначно. Используйте a.empty , a.bool(), a.item(), a.any() или a.all() .

 import pandas as pd
from datetime import datetime, timedelta

department = []

if (df_final['resultaatdatum'] < (df_final['date_admission']    timedelta(days =   3))) and (df_final['resultaatdatum'] > (df_final['date_admission']   timedelta(days = - 1))):
    department.append(df_final['admissiondepartment'])
else:
    department.append(NaN)
    
df_final['department'] = department
  

Я должен получить df_final['department'] = [NaN, 'INT', 'ER']

Ответ №1:

Используйте iterrows. серия не может дать одно логическое значение, которое if ожидает.

 for index,row in df_final.iterrows():
    if (df_final['date_rslt'][index] < (df_final['date_admis'][index]    timedelta(days =   3))) and (df_final['date_rslt'][index] > (df_final['date_admis'][index]   timedelta(days = - 1))):
        department.append(df_final['dept'][index])
    else:
        department.append(np.NaN)
  

вывод:

 [nan, 'INT', 'ER']
  

Ответ №2:

Вы можете сделать это без списка таким образом:

 import numpy as np

m =(df['date_rslt'] < (df['date_admis']    timedelta(days =   3))) amp; (df['date_rslt'] > (df['date_admis']   timedelta(days = - 1)))

df.loc[~m,"dept"] = np.nan
  

Вывод:

     pin    date_rslt    date_admis  dept
0   1522    2018-04-18  2017-12-14  NaN
1   1522    2018-04-18  2018-04-17  INT
2   3830    2018-04-09  2018-04-08  ER
  

Ответ №3:

Если вы хотите узнать, какие результаты тестов пациентов были получены между минус 1 и 3 днями после поступления в больницу, тогда вы можете просто запросить данные:

 df['date_rslt'] = pd.to_datetime(df['date_rslt']) # will need to be datetime
df['date_admis'] = pd.to_datetime(df['date_admis']) # will need to be datetime

df['admis_plus_3'] = df['date_admis']   pd.Timedelta(days=3)
df['admis_minus_1'] = df['date_admis']   pd.Timedelta(days=-1)

patients = df.query('(date_rslt < admis_plus_3) amp; (date_rslt > admis_minus_1)')
  

Если вам нужен список отделов из этого, вы можете просто сделать : patients['dept'] .

Или вы всегда можете выполнить слияние с другим набором данных, если вам нужно включить NaN строк обратно в данные.