我有一个如下所示的数据框,我正在尝试计算每种药物的日剂量。在下表中,我有一种药物,但在实际表中,我有多种药物。
让我对表格和场景进行简要说明。 ID列是唯一的患者ID,“开始和结束”列表示药物以该速率开始和结束的时间,“小时”列表示该ID从开始到结束之间的小时数,“速率”列显示的是什么速率在该时间段内使用该ID的药物。该表格的设计方式是每个ID的每个费率都有一个开始和结束日期。
在医院中,如果他们要计算每日总剂量,则要从今天上午7点到第二天上午7点进行计算,而不是从午夜到午夜进行计算。
ID START END DRUG RATE HOURS
15114299 2011-03-18 18:23:00 2011-03-19 20:59:59 morphine 0.03 26.6
15114299 2011-03-19 21:00:00 2011-03-20 01:29:59 morphine 0.1 4.4
15340823 2011-02-18 16:00:00 2011-02-19 03:09:59 morphine 0.1 11.16
15340823 2011-02-19 15:30:00 2011-02-19 21:59:59 morphine 0.05 6.49
15621352 2011-04-20 03:44:00 2011-04-20 13:41:59 morphine 0.05 9.96
15621352 2011-04-20 13:42:00 2011-04-20 23:59:59 morphine 0.5 10.29
15775791 2011-07-21 19:00:00 2011-07-24 03:59:59 morphine 0.1 56.99
15775791 2011-07-24 04:00:00 2011-07-24 14:14:59 morphine 0.05 10.24
15947559 2011-07-05 19:40:00 2011-07-06 05:43:59 morphine 0.1 10.06
15947559 2011-07-06 05:44:00 2011-07-09 01:59:59 morphine 0.15 68.26
15947559 2011-07-09 02:00:00 2011-07-09 18:59:59 morphine 0.1 16.99
15947559 2011-07-14 19:30:00 2011-07-15 18:29:59 morphine 0.1 22.99
15947559 2011-07-15 18:30:00 2011-07-17 02:59:59 morphine 0.15 32.49
15947559 2011-07-17 03:00:00 2011-07-17 08:59:59 morphine 0.1 5.99
15947559 2011-07-17 09:00:00 2011-07-17 16:59:59 morphine 0.075 7.99
在示例数据框中可以看到,第一种药物治疗了26.6小时,我想要做的是将该记录分成两部分,如下所示,并有一个day列将有助于分组并求和最后的每一天。
期望的DF:
ID START END DRUG RATE HOURS Days
15114299 2011-03-18 18:23:00 2011-03-19 06:59:59 morphine 0.03 12.62 Day1
15114299 2011-03-19 07:00:00 2011-03-19 20:59:59 morphine 0.03 14 Day2
15114299 2011-03-19 21:00:00 2011-03-20 01:29:59 morphine 0.1 4.5 Day2
15340823 2011-02-18 16:00:00 2011-02-19 03:09:59 morphine 0.1 11.16 Day1
15340823 2011-02-19 15:30:00 2011-02-19 21:59:59 morphine 0.05 6.49 Day2
15621352 2011-04-20 03:44:00 2011-04-20 06:59:59 morphine 0.05 3.27 Day1
15621352 2011-04-20 07:00:00 2011-04-20 13:41:59 morphine 0.05 6.70 Day2
15621352 2011-04-20 13:42:00 2011-04-20 23:59:59 morphine 0.5 10.29 Day2
15775791 2011-07-21 19:00:00 2011-07-22 06:59:59 morphine 0.1 12 Day1
15775791 2011-07-22 07:00:00 2011-07-23 06:59:59 morphine 0.1 24 Day2
15775791 2011-07-23 07:00:00 2011-07-24 03:59:59 morphine 0.1 21 Day3
15775791 2011-07-24 04:00:00 2011-07-24 06:59:59 morphine 0.05 3 Day3
15775791 2011-07-24 07:00:00 2011-07-24 14:14:59 morphine 0.05 7.25 Day4
15947559 2011-07-05 19:40:00 2011-07-06 05:43:59 morphine 0.1 10.06 Day1
15947559 2011-07-06 05:44:00 2011-07-06 06:59:59 morphine 0.15 1.27 Day1
15947559 2011-07-06 07:00:00 2011-07-07 06:59:59 morphine 0.15 24 Day2
15947559 2011-07-07 07:00:00 2011-07-08 06:59:59 morphine 0.15 24 Day3
15947559 2011-07-08 07:00:00 2011-07-09 01:59:59 morphine 0.15 19 Day4
15947559 2011-07-09 02:00:00 2011-07-09 06:59:59 morphine 0.1 5 Day4
15947559 2011-07-09 07:00:00 2011-07-09 18:59:59 morphine 0.1 12 Day5
15947559 2011-07-14 19:30:00 2011-07-15 06:59:59 morphine 0.1 11.50 Day6
15947559 2011-07-15 07:00:00 2011-07-15 18:29:59 morphine 0.1 11.50 Day7
15947559 2011-07-15 18:30:00 2011-07-16 06:59:59 morphine 0.15 12.50 Day7
15947559 2011-07-16 07:00:00 2011-07-17 02:59:59 morphine 0.15 20 Day8
15947559 2011-07-17 03:00:00 2011-07-17 06:59:59 morphine 0.1 4 Day8
15947559 2011-07-17 07:00:00 2011-07-17 08:59:59 morphine 0.1 2 Day9
15947559 2011-07-17 09:00:00 2011-07-17 16:59:59 morphine 0.075 8 Day9
(为了更加清楚和理解,我在两个ID之间创建了空格)
我尝试了以下代码。
test = pd.concat([pd.DataFrame({'START': pd.date_range(row['START'], row['END'], freq='D'),
'PERSON_ID': row['ID'],
'DRUG': row['DRUG'],
'RATE': row['RATE']}, columns=['ID', 'START', 'DRUG', 'RATE'])
for i, row in df.iterrows()], ignore_index=False)
,但这会以以下方式创建数据框。
ID START DRUG RATE
15114299 2011-03-18 18:23:00 morphine 0.03
15114299 2011-03-19 18:23:00 morphine 0.03
15114299 2011-03-19 21:00:00 morphine 0.1
15340823 2011-02-18 16:00:00 morphine 0.1
15340823 2011-02-19 15:30:00 morphine 0.05
15621352 2011-04-20 03:44:00 morphine 0.05
15621352 2011-04-20 13:42:00 morphine 0.5
15775791 2011-07-21 19:00:00 morphine 0.1
15775791 2011-07-22 19:00:00 morphine 0.1
15775791 2011-07-23 19:00:00 morphine 0.1
15775791 2011-07-24 04:00:00 morphine 0.05
15947559 2011-07-05 19:40:00 morphine 0.1
15947559 2011-07-06 05:44:00 morphine 0.15
15947559 2011-07-07 05:44:00 morphine 0.15
15947559 2011-07-08 05:44:00 morphine 0.15
15947559 2011-07-09 02:00:00 morphine 0.1
15947559 2011-07-14 19:30:00 morphine 0.1
15947559 2011-07-15 18:30:00 morphine 0.15
15947559 2011-07-16 18:30:00 morphine 0.15
15947559 2011-07-17 03:00:00 morphine 0.1
15947559 2011-07-17 09:00:00 morphine 0.075
如果有人可以帮助我解决这个问题,我将非常感谢。很高兴提供其他详细信息。
答案 0 :(得分:2)
从定义此类变量开始:
h7 = pd.Timedelta('7H')
s1 = pd.Timedelta('1S')
(将使用多次)。
要将每一行“扩展”为一系列行(每天), 定义以下功能:
def expand(row):
tm1, tm2 = row.START, row.END
t1 = tm1 if type(tm1).__name__ == 'Timestamp' else pd.to_datetime(tm1)
t2 = tm2 if type(tm2).__name__ == 'Timestamp' else pd.to_datetime(tm2)
rng = pd.date_range(start=t1 - h7, end=t2 - h7, freq='1D', closed='right',
normalize=True) + pd.Timedelta('7H')
ind = pd.DatetimeIndex([t1, *rng, t2 + s1])
res = pd.DataFrame({'ID': row.ID, 'START': ind[:-1], 'END': ind[1:] - s1,
'DRUG': row.DRUG, 'RATE': row.RATE})
res['HOURS'] = (res.END - res.START).dt.total_seconds().div(3600).round(2)
return res
并应用它,创建结果表:
df2 = pd.concat(df.apply(expand, axis=1).tolist(), ignore_index=True)
现在,没有天列。
然后添加天列,执行:
df2['Days'] = 'Day' + ((df2.START - h7).dt.date - df2.groupby('ID')
.START.transform('first').dt.date).dt.days.add(1).astype(str)
“天”号(“ <天”之后的“ ”)是当前日期之间的差 以及第一行的日期+ 1。
由于从当前日期减去了 h7 ,因此此代码可以正常工作, 即使在Midnignt和7点之间发生更改。
要显示结果,请运行:
df2.sort_values('ID')
要跟踪该解决方案的思想,请分别运行每个语句,然后 查看结果。