04. Transforming Patient Therapy Intervals to a Daily Summary

Previous title: 04. Format MIMIC therapy (one)

This script demonstrates how to process time-interval data, a common format in medical records like the MIMIC-III dataset. It starts with a table where each row represents an antibiotic therapy with a specific start and end date.

The main goal is to transform this interval-based data into a daily summary. This is achieved by using pd.date_range to generate all dates within each therapy period and then using the explode() method to create a distinct row for each day. The final output is a count of how many days each unique combination of therapies was administered to the patient.

18 # Generic libraries
19 import pandas as pd
20
21 # Show in terminal
22 TERMINAL = False

First, lets load and do some basic formatting on the data.

27 # -----------------------------
28 # Constants
29 # -----------------------------
30 # Path
31 path = './data/mimic-therapy/One_patient_condensed_10656173.csv'
32 path = './data/mimic-therapy/One_patient_condensed_11803145.csv'
33
34 # -----------------------------
35 # Load data
36 # -----------------------------
37 # Read data
38 data = pd.read_csv(path,
39     dayfirst=True,
40     parse_dates=['starttime',
41                  'stoptime'])
42
43 # Keep only useful columns
44 data = data[['subject_id',
45              'antibiotic',
46              'route',
47              'starttime',
48              'stoptime']]
49
50 # Reformat (ignore time information)
51 data.starttime = data.starttime.dt.date
52 data.stoptime = data.stoptime.dt.date
53
54 # Show
55 if TERMINAL:
56     print("\nData:")
57     print(data)
58 data
subject_id antibiotic route starttime stoptime
0 11803145 Vancomycin IV 2159-01-20 2159-01-20
1 11803145 Piperacillin-Tazobactam IV 2159-01-20 2159-01-20
2 11803145 Piperacillin-Tazobactam IV 2159-01-20 2159-01-20
3 11803145 Piperacillin-Tazobactam IV 2159-01-20 2159-01-25
4 11803145 Vancomycin IV 2159-01-21 2159-01-22
5 11803145 Vancomycin IV 2159-01-22 2159-01-23
6 11803145 Vancomycin IV 2159-01-23 2159-01-23
7 11803145 Meropenem IV 2159-01-25 2159-01-26
8 11803145 Meropenem IV 2159-01-25 2159-01-26
9 11803145 Meropenem IV 2159-01-26 2159-02-02
10 11803145 Vancomycin IV 2159-01-26 2159-01-26
11 11803145 Vancomycin IV 2159-01-26 2159-01-27
12 11803145 Vancomycin IV 2159-01-26 2159-01-29
13 11803145 Vancomycin IV 2159-01-28 2159-01-29
14 11803145 Tobramycin Sulfate IV 2159-01-28 2159-01-29
15 11803145 Azithromycin IV 2159-01-28 2159-01-30
16 11803145 MetRONIDAZOLE (FLagyl) IV 2159-01-29 2159-02-01
17 11803145 Vancomycin IV 2159-01-30 2159-01-31
18 11803145 Vancomycin IV 2159-02-01 2159-02-02
19 11803145 Meropenem IV 2159-02-03 2159-02-04
20 11803145 Vancomycin IV 2159-02-03 2159-02-04
21 11803145 Vancomycin IV 2159-02-03 2159-02-04


Lets transform the data

63 # -----------------------------
64 # Transform data
65 # -----------------------------
66 # .. note: The closed parameter indicates whether to include
67 #          the first and/or last samples. None will keep both,
68 #          left will keep only start date and right will keep
69 #          also the right date.
70 # Create column with date range
71 data['startdate'] = data.apply(lambda x:
72     pd.date_range(start=x['starttime'],
73                   end=x['stoptime'],
74                   inclusive='left',         # ignoring right
75                   freq='D') ,axis=1)
76
77 # Explode such column
78 data = data.explode('startdate')
79
80 # Create daily therapies
81 aux = data.groupby('startdate') \
82     .apply(lambda x: sorted(x.antibiotic \
83         .str.lower().str.strip().unique().tolist()))
84
85 # Include missing days
86 aux = aux.asfreq('1D')

Lets see the formatted data

91 # Show
92 if TERMINAL:
93     print("\nFormatted:")
94     print(aux)
95 aux

Out:

startdate
2159-01-20                [piperacillin-tazobactam, vancomycin]
2159-01-21                [piperacillin-tazobactam, vancomycin]
2159-01-22                [piperacillin-tazobactam, vancomycin]
2159-01-23                [piperacillin-tazobactam, vancomycin]
2159-01-24                            [piperacillin-tazobactam]
2159-01-25                                          [meropenem]
2159-01-26                              [meropenem, vancomycin]
2159-01-27                              [meropenem, vancomycin]
2159-01-28    [azithromycin, meropenem, tobramycin sulfate, ...
2159-01-29    [azithromycin, meropenem, metronidazole (flagyl)]
2159-01-30      [meropenem, metronidazole (flagyl), vancomycin]
2159-01-31                  [meropenem, metronidazole (flagyl)]
2159-02-01                              [meropenem, vancomycin]
2159-02-02                                                  NaN
2159-02-03                              [meropenem, vancomycin]
Freq: D, dtype: object

Lets count the number of days

100 # Show
101 if TERMINAL:
102     print("\nTherapies (number of days)")
103     print(aux.value_counts())
104 aux.value_counts()

Out:

[piperacillin-tazobactam, vancomycin]                        4
[meropenem, vancomycin]                                      4
[piperacillin-tazobactam]                                    1
[meropenem]                                                  1
[azithromycin, meropenem, tobramycin sulfate, vancomycin]    1
[azithromycin, meropenem, metronidazole (flagyl)]            1
[meropenem, metronidazole (flagyl), vancomycin]              1
[meropenem, metronidazole (flagyl)]                          1
Name: count, dtype: int64

Total running time of the script: ( 0 minutes 0.027 seconds)

Gallery generated by Sphinx-Gallery