全国服务热线:400-6136-679

位置:南京CDA数据分析师培训机构 > 学校动态 > 从开始到结束日期自增扩充数据

从开始到结束日期自增扩充数据

来源:南京CDA数据分析师培训机构时间:2022/12/9 15:33:20

  糖尿病是较常见的慢性非传染性疾病之一。流行病学调查显示,我国约11%的成年人患有糖尿病,而在住院患者中这一比例更高。

  住院期间将长期服用药物,医院系统在检测到医嘱级别为长期医嘱时,会根据医嘱单上医嘱开始日期及时间,每天按时自动创建当日医嘱单,在没有停止或更改的情况下,其医嘱内容与上医嘱内容一致。患者根据每天的医嘱单上的内容按时按量服用药物,直至医生停止患者用药。

  由于是重复内容,系统为节约存储空间,并未记录每天自动创建的重复医嘱单。但在做数据分析时,需要进行临床场景重现。

  一、需求描述

  有如下数据,columns = ['医嘱日期', '医嘱时间', '医嘱开始日期', '医嘱开始时间','医嘱级', '停止日期', '停止时间', '项目名称']

时间序列,从开始到结束日期自增扩充数据

  现要求从医嘱开始日期到停止日期,按照日期自增逻辑扩充数据,其中自增的日期的医嘱开始时间为当日的01:00:00。结果如下图:

二、方法一,表格合并

  先上代码

  def long_advice(item):    # 逐条处理,传入Series     # 构建医嘱单内容表     item_df1 = pd.DataFrame(data=np.reshape(item.values,(1,-1)),columns=item.index)    item_df2 = item_df1.copy()    item_df2['医嘱开始时间'] = parse('01:00:00').time()    item_df = pd.concat([item_df1, item_df2]).drop(columns='医嘱开始日期').reset_index(drop=True)        # 构建时间序列索引表     # 扩展的医嘱日期的医嘱时间为01:00:00,医嘱开始日期的医嘱时间为原有的医嘱时间     date_range_left = pd.DataFrame(        data=parse('01:00:00').time(),        index=pd.date_range(start=item.医嘱开始日期, end=item.停止日期),        columns= ['医嘱开始时间']                                  ).reset_index().rename(columns={'index':'医嘱开始日期'})    date_range_left.loc[0,'医嘱开始时间']= item.医嘱时间        # 以时间序列索引表为左表,以时间序列内容表为右表     date_range_df = pd.merge(date_range_left                         ,item_df                         ,on = '医嘱开始时间'                          ,how='left')    return  date_range_df

  步骤详解

  导入Python包

  import pandas as pd import numpy as np from datetime import datetime from dateutil.parser import parse

  查看原始数据

  # 前面步骤略,直接从主题开始 >>> item 医嘱日期      2019-08-05 00:00:00 医嘱时间                 16:34:25 医嘱开始日期    2019-08-05 00:00:00 医嘱开始时间               16:34:42 医嘱级                    长期医嘱 停止日期      2019-08-27 00:00:00 停止时间                 10:49:26 项目名称           格华止(500mg×30片) Name: 0, dtype: object

  pd.Series转pd.DataFrame

  # 纵向向array转横向array >>> np.reshape(item.values,(1,-1))array([[Timestamp('2019-08-05 00:00:00'), datetime.time(16, 34, 25),        Timestamp('2019-08-05 00:00:00'), datetime.time(16, 34, 42),        '长期医嘱', Timestamp('2019-08-27 00:00:00'),        datetime.time(10, 49, 26)]], dtype=object) >>> item_df1 = pd.DataFrame(data=np.reshape(item.values,(1,-1)),columns=item.index) # 或者 >>> pd.DataFrame(item).T

  输出

时间序列,从开始到结束日期自增扩充数据

构建医嘱单内容表

  # 首先创建副本,避免更改原表 >>> item_df2 = item_df1.copy() # 创建datetime.time()格式的'01:00:00' >>> parse('01:00:00').time()datetime.time(1, 0) # 将原来的时间更换为新的时间 >>> item_df2['医嘱开始时间'] = parse('01:00:00').time() # 合并两表 >>> item_df = pd.concat([item_df1, item_df2]                       ).drop(columns='医嘱开始日期').reset_index(drop=True)

  输出

时间序列,从开始到结束日期自增扩充数据

  至此医嘱单内容已创建完毕,接下来需要创建自增的时间序列,并以时间序列做主表,以医嘱单内容表做从表,进行表与表之间的连接。

  构建时间序列索引表

  从医嘱开始日期到停止日期创建pd.date_range() 索引,以医嘱开始时间等于'01:00:00' 为内容创建DataFrame,并重置索引并重命名,还原医嘱开始当日的开始时间。因为只要自增的那部分日期的医嘱时间为'01:00:00' ,而开始的天还是按照原来的开始时间。

  >>> date_range_left = pd.DataFrame(data=parse('01:00:00').time(),                                   index=pd.date_range(start=item.医嘱开始日期, end=item.停止日期),                                   columns= ['医嘱开始时间']                                  ).reset_index().rename(columns={'index':'医嘱开始日期'}) >>> date_range_left.loc[0,'医嘱开始时间']= item.医嘱开始时间 >>> date_range_left

  输出

时间序列,从开始到结束日期自增扩充数据

  这里主要用到了pd.date_range() 方法,可参考《时间序列》

  合并时间序列索引表与医嘱单内容表

  >>> date_range_df = pd.merge(date_range_left                             , item_df                             , on='医嘱开始时间'                              , how='left')

  至此方法一已完成。

  三、方法二,时间戳重采样

  既然方法一已经提到用时间序列内pd.date_range() 方法,何不直接用升采用及插值的方法完成。

  需要了解pandas里使用时间序列处理数据问题,可移步至《时间序列》。

  上代码

  def long_advice_2(item):    # 逐条处理,传入Series     # 构建医嘱单内容表     item_df1 = pd.DataFrame(data=np.reshape(item.values,(1,-1)),columns=item.index)    item_df2 = item_df1.copy()    item_df2['医嘱开始时间'] = parse('01:00:00').time()    item_df2['医嘱开始日期'] = item_df2['停止日期']    item_df = pd.concat([item_df1, item_df2]).reset_index(drop=True)    # 构建时间序列,将起始时间转换为 DatetimeIndex(['2019-08-05', '2019-08-27'], dtype='datetime64[ns]', freq=None)     frame = pd.DataFrame(item_df.drop(columns=['医嘱开始日期']).values,             index=pd.to_datetime(item_df.医嘱开始日期.values),             columns=item_df.drop(columns=['医嘱开始日期']).columns)        # 时间戳重采样,resampling的填充和插值方式跟fillna和reindex的一样     date_range_df = frame.resample('D').bfill().reset_index().rename(columns={'index':'医嘱开始日期'})    return date_range_df

  构建医嘱单内容表

  其中构建医嘱单内容表与前面类似,其不同之处为保留医嘱开始日期,将第二个开始日期替换为停止日期,以便后面转换为pd.date_range()日期范围。

  >>> item_df1 = pd.DataFrame(data=np.reshape(item.values,(1,-1)),columns=item.index) >>> item_df2 = item_df1.copy() >>> item_df2['医嘱开始时间'] = parse('01:00:00').time() >>> item_df2['医嘱开始日期'] = item_df2['停止日期'] >>> item_df = pd.concat([item_df1, item_df2]).reset_index(drop=True) >>> item_df

  输出

时间序列,从开始到结束日期自增扩充数据

构建时间序列

  >>> # DataFrame的轴索引或列的日期转换为DatetimeIndex() >>> pd.to_datetime(item_df.医嘱开始日期.values)DatetimeIndex(['2019-08-05', '2019-08-27'], dtype='datetime64[ns]', freq=None) >>> frame = pd.DataFrame(item_df.drop(columns=['医嘱开始日期']).values,                 index=pd.to_datetime(item_df.医嘱开始日期.values),                 columns=item_df.drop(columns=['医嘱开始日期']).columns) >>> frame

  输出

时间序列,从开始到结束日期自增扩充数据

升采样及插值

  时间戳重采样,resampling的填充和插值方式跟fillna和reindex的一样

  >>> date_range_df = frame.resample('D').bfill() >>> date_range_df

  输出

时间序列,从开始到结束日期自增扩充数据

  较后在重置索引并重命名即可。

  四、要点总结

  构建自增时间序列

  时间序列内容,即需要重复的医嘱单准备

  医嘱开始时间准备,D与其后几天的时间不同

  插值,根据实际情况使用前插值(.ffill())或后插值(.bfill())

  当然,除了上述的两种方法,如果您有更好的方法,欢迎搭讪交流。

领取试听课
每天限量名额,先到先得

尊重原创文章,转载请注明出处与链接:http://www.peixun360.com/6186/news/582457/违者必究! 以上就是南京CDA数据分析师培训机构 小编为您整理 从开始到结束日期自增扩充数据的全部内容。

温馨提示:提交留言后老师会第一时间与您联系!热线电话:400-6136-679