62  抗生素使用强度数据归整、查询与计算

62.1 计划

62.2 归整数据业务流程

以病人为单位,每日数据作为一行。
要求每天必须导出医嘱,最好是下午下班前导出。

flowchart TD

A((每日医嘱)) -->|每行添加医嘱导出时间| B["功能:<br> 1. 日期查询 2.确定当天实际使用次数"]

B --> B1{有无抗生素医嘱} 

B1 -->|无| B2[保留计算床天数]
B2 -->|0| C14

B1 -->|有| C1["按病人(住院号)分组"]

C1 --> C2{每个病人有无转科信息}

C2 -->|无| C3[无转科信息部分病人]
C2 -->|有| C4[有转科信息部分病人]

C3 --> C5[判断抗生素使用次数]

C5 --> C6{临嘱}

C6 -->|开抗生素时间为医嘱导出当天| C7{停嘱时间}

C7 -->|空| C8[当天医嘱已执行] -->|根据使用频次转换| C14[实际使用次数]
C7 -->|非空| C9["医嘱未执行(不论停医嘱与开医嘱时间间隔)"] -->|0| C14

C5 --> C10{长嘱}

C10 -->|开抗生素时间早于医嘱导出当天| C11{停嘱时间}

C11 -->|空| C12[当天医嘱已执行] -->|根据使用频次转换| C14
C11 -->|非空| C13{停抗生素时间与医嘱导出日期天数差}

C13 -->|小于0| C13A[停医嘱时间早于医嘱导出日期]
C13 -->|大于0| C13B[停医嘱时间晚于医嘱导出日期]
C13 -->|等于0| C13C[停医嘱时间等于医嘱导出日期]

C13A -->|0| C14
C13B --> C12
C13C --> C13C1[医嘱导出当天停的长嘱] -->|根据停嘱时间与当天零点的时间差和频次转换| C14



C4 --> C15["确定医嘱真正发生的科室"]

C15 -->|修正科室| D[按照无转科信息处理]

D -->|合并| C3

C14 --> C14A[合并数据] -->|选择必需列| E[数据库] --> F((归整数据结束))

抗生素使用强度计算流程图

import pandas as pd 
import os
import re

62.3 处理当天数据

files = (os
         .listdir('data/dailyantibiotics/')
        )

files.sort()

files
['抗生素医嘱-2023-01-01.xlsx',
 '抗生素医嘱-2023-01-02.xlsx',
 '抗生素医嘱-2023-01-03.xlsx',
 '抗生素医嘱-2023-01-04.xlsx',
 '抗生素医嘱-2023-01-05.xlsx',
 '抗生素医嘱-2023-01-10.xlsx',
 '抗生素医嘱-2023-01-11.xlsx',
 '抗生素医嘱-2023-01-12.xlsx',
 '抗生素医嘱-2023-01-13.xlsx',
 '抗生素医嘱-2023-01-16.xlsx',
 '抗生素医嘱-2023-01-17.xlsx',
 '抗生素医嘱-2023-01-18.xlsx',
 '抗生素医嘱-2023-01-19.xlsx',
 '抗生素医嘱-2023-01-20.xlsx',
 '抗生素医嘱-2023-01-28.xlsx',
 '抗生素医嘱-2023-01-29.xlsx',
 '抗生素医嘱-2023-01-30.xlsx',
 '抗生素医嘱-2023-01-31.xlsx']

62.3.1 导入数据

f = files[0]
print(f)
df = (
    pd
    .read_excel(
        f"data/dailyantibiotics/{f}",
        dtype = {'住院号':str}   # 住院号以字符读入
    )
    .query('~管床医生.isin(["胡顺锦", "超级管理"])')  # 排除异常数据
    .assign(
            导出医嘱日期= pd.to_datetime(
                re.search('\d+-\d+-\d+', f).group(0)
            )
        )  # 添加导出医嘱日期列,供后期通过日期查询
)

print(f"共{len(df.住院号.unique())}个病人")

print(df.info())

df.head()
抗生素医嘱-2023-01-01.xlsx
共2447个病人
<class 'pandas.core.frame.DataFrame'>
Int64Index: 7496 entries, 0 to 7501
Data columns (total 16 columns):
 #   Column  Non-Null Count  Dtype         
---  ------  --------------  -----         
 0   入院时间    7496 non-null   datetime64[ns]
 1   科室名称    7496 non-null   object        
 2   病人姓名    7496 non-null   object        
 3   住院号     7496 non-null   object        
 4   床号      7496 non-null   object        
 5   管床医生    7496 non-null   object        
 6   抗生素名称   6210 non-null   object        
 7   医嘱类型    6210 non-null   object        
 8   抗生素医嘱   6210 non-null   object        
 9   用量      6210 non-null   float64       
 10  单位      6210 non-null   object        
 11  频次      6210 non-null   object        
 12  开抗生素时间  6210 non-null   datetime64[ns]
 13  停抗生素时间  1885 non-null   datetime64[ns]
 14  转科信息    3028 non-null   object        
 15  导出医嘱日期  7496 non-null   datetime64[ns]
dtypes: datetime64[ns](4), float64(1), object(11)
memory usage: 995.6+ KB
None
入院时间 科室名称 病人姓名 住院号 床号 管床医生 抗生素名称 医嘱类型 抗生素医嘱 用量 单位 频次 开抗生素时间 停抗生素时间 转科信息 导出医嘱日期
0 2022-12-31 20:02:44.558 产科 蔡晨韵 620319 15 曾日明 (新福欣)注射用头孢呋辛钠#J 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(新福欣)注射用... 1.50 g Qd 2023-01-01 08:08:28.915 NaT NaN 2023-01-01
1 2022-12-31 20:02:44.558 产科 蔡晨韵 620319 15 曾日明 (新福欣)注射用头孢呋辛钠#J 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(新福欣)注射用... 0.75 g Q12h 2023-01-01 10:59:31.368 NaT NaN 2023-01-01
2 2023-01-01 09:46:43.170 产科 蔡晨韵B 620319B 15B 曾日明 NaN NaN NaN NaN NaN NaN NaT NaT NaN 2023-01-01
3 2022-12-31 08:09:28.628 产科 陈楚敏 791203 11 陈顺娣 (新福欣)注射用头孢呋辛钠#J 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(新福欣)注射用... 1.50 g Qd 2022-12-31 09:02:40.382 NaT NaN 2023-01-01
4 2022-12-31 08:09:28.628 产科 陈楚敏 791203 11 陈顺娣 (新福欣)注射用头孢呋辛钠#J 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(新福欣)注射用... 0.75 g Q12h 2022-12-31 14:15:32.654 NaT NaN 2023-01-01

62.3.2 科室名称

df.科室名称.unique()
array(['产科', '创伤骨科', '儿科', '耳鼻喉科', '妇科二区', '妇科一区', '肝胆胰肛肠外科', '感染科',
       '关节四肢骨病外科', '呼吸与危重症二区', '呼吸与危重症一区', '急诊ICU', '急诊综合病区', '脊柱外二区',
       '脊柱外一区', '甲状腺血管外科', '康复科', '口腔科', '泌尿外二科', '泌尿外一科', '内分泌科', '皮肤科',
       '全科医学科', '日间化疗中心', '乳腺科', '烧伤整形', '神经内二科', '神经内科一区', '神经内三科',
       '神经外二科', '神经外一科', '神经重症科', '肾内二科', '肾内科', '肾内血液净化中心', '手足显微外科',
       '外科ICU', '胃肠外科二区', '胃肠外科一区', '消化内一科', '小儿外、疝外科', '新生儿科', '心血管内二科',
       '心血管内一科', '心血管外科', '心脏重症监护病房(CCU)', '胸外科', '血液风湿科', '血液透析室(新福门诊部)',
       '眼科', '医保特门诊2', '中医肛肠科', '肿瘤二科', '肿瘤科三区', '肿瘤一科', '重症医学科',
       '重症医学科三区', '重症医学科五区', '综合科', '综合科特需病房'], dtype=object)

62.3.3 没有开抗生素的病人

没有开抗生素的病人,用于计床天数,不能删除。
当天医嘱中没有开抗生素的病人和开了抗生素的病人互不包含。

df_without_antibiotics = (
    df
    # .groupby('住院号')
    # .filter(lambda group : ~group['抗生素医嘱'].notna().all())   # 每个病人作为一组,转科信息是否全部为空
    .query('抗生素医嘱.isna()')
)

df_without_antibiotics.head()
入院时间 科室名称 病人姓名 住院号 床号 管床医生 抗生素名称 医嘱类型 抗生素医嘱 用量 单位 频次 开抗生素时间 停抗生素时间 转科信息 导出医嘱日期
2 2023-01-01 09:46:43.170 产科 蔡晨韵B 620319B 15B 曾日明 NaN NaN NaN NaN NaN NaN NaT NaT NaN 2023-01-01
5 2022-12-31 12:22:27.152 产科 陈楚敏B 791203B 11B 陈顺娣 NaN NaN NaN NaN NaN NaN NaT NaT NaN 2023-01-01
10 2023-01-02 19:17:40.015 产科 黄志琼 950467 23 陈尚萍 NaN NaN NaN NaN NaN NaN NaT NaT NaN 2023-01-01
11 2023-01-02 12:42:24.541 产科 李丹 950427 07 崔剑梅 NaN NaN NaN NaN NaN NaN NaT NaT NaN 2023-01-01
12 2023-01-02 15:33:14.231 产科 李丹B 950427B 07B 黎秀荣 NaN NaN NaN NaN NaN NaN NaT NaT NaN 2023-01-01

62.3.4 开了抗生素的病人

df_with_antibiotics = (
    df
    .query('抗生素医嘱.notna()')
)

df_with_antibiotics.head()
入院时间 科室名称 病人姓名 住院号 床号 管床医生 抗生素名称 医嘱类型 抗生素医嘱 用量 单位 频次 开抗生素时间 停抗生素时间 转科信息 导出医嘱日期
0 2022-12-31 20:02:44.558 产科 蔡晨韵 620319 15 曾日明 (新福欣)注射用头孢呋辛钠#J 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(新福欣)注射用... 1.50 g Qd 2023-01-01 08:08:28.915 NaT NaN 2023-01-01
1 2022-12-31 20:02:44.558 产科 蔡晨韵 620319 15 曾日明 (新福欣)注射用头孢呋辛钠#J 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(新福欣)注射用... 0.75 g Q12h 2023-01-01 10:59:31.368 NaT NaN 2023-01-01
3 2022-12-31 08:09:28.628 产科 陈楚敏 791203 11 陈顺娣 (新福欣)注射用头孢呋辛钠#J 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(新福欣)注射用... 1.50 g Qd 2022-12-31 09:02:40.382 NaT NaN 2023-01-01
4 2022-12-31 08:09:28.628 产科 陈楚敏 791203 11 陈顺娣 (新福欣)注射用头孢呋辛钠#J 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(新福欣)注射用... 0.75 g Q12h 2022-12-31 14:15:32.654 NaT NaN 2023-01-01
6 2022-12-28 15:29:51.940 产科 陈坤枚 931359 06 崔剑梅 (新泰同)注射用头孢唑林钠#J 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(新泰同)注射用... 2.00 g Qd 2022-12-29 09:08:33.410 NaT NaN 2023-01-01

62.3.5 转科信息全为空的病人

指开了抗生素的病人,下同

# 查看有无转科信息的病人数

transfer_info_count = (
    df_with_antibiotics
    .groupby('住院号')
    .agg({'转科信息': lambda x: x.isna().all()})   # 每个病人作为一组,转科信息是否全部为空
    .value_counts()
)

transfer_info_count
转科信息 
True     883
False    278
dtype: int64
# 提取无转科信息部分病人

df_without_transfer = (
    df_with_antibiotics
    .groupby('住院号')
    .filter(lambda group : group['转科信息'].isna().all())   # 每个病人作为一组,转科信息是否全部为空
    
)

df_without_transfer.住院号.unique().shape
(883,)

62.3.5.1 临嘱部分

# 无转科信息病人的临嘱

df_without_transfer_lsyz = (
    df_without_transfer.query('医嘱类型=="临嘱"')
)

print(df_without_transfer_lsyz.shape)

df_without_transfer_lsyz.head()
(1945, 16)
入院时间 科室名称 病人姓名 住院号 床号 管床医生 抗生素名称 医嘱类型 抗生素医嘱 用量 单位 频次 开抗生素时间 停抗生素时间 转科信息 导出医嘱日期
0 2022-12-31 20:02:44.558 产科 蔡晨韵 620319 15 曾日明 (新福欣)注射用头孢呋辛钠#J 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(新福欣)注射用... 1.50 g Qd 2023-01-01 08:08:28.915 NaT NaN 2023-01-01
1 2022-12-31 20:02:44.558 产科 蔡晨韵 620319 15 曾日明 (新福欣)注射用头孢呋辛钠#J 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(新福欣)注射用... 0.75 g Q12h 2023-01-01 10:59:31.368 NaT NaN 2023-01-01
3 2022-12-31 08:09:28.628 产科 陈楚敏 791203 11 陈顺娣 (新福欣)注射用头孢呋辛钠#J 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(新福欣)注射用... 1.50 g Qd 2022-12-31 09:02:40.382 NaT NaN 2023-01-01
4 2022-12-31 08:09:28.628 产科 陈楚敏 791203 11 陈顺娣 (新福欣)注射用头孢呋辛钠#J 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(新福欣)注射用... 0.75 g Q12h 2022-12-31 14:15:32.654 NaT NaN 2023-01-01
6 2022-12-28 15:29:51.940 产科 陈坤枚 931359 06 崔剑梅 (新泰同)注射用头孢唑林钠#J 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(新泰同)注射用... 2.00 g Qd 2022-12-29 09:08:33.410 NaT NaN 2023-01-01
# 开抗生素时间是不是导出医嘱日期当天

df_without_transfer_lsyz = (
    df_without_transfer_lsyz
    .assign(
        开抗生素时间与医嘱导出日期天数差 = (
            (df_without_transfer_lsyz.开抗生素时间 - df_without_transfer_lsyz.导出医嘱日期)
            # .apply(lambda x : x.days) 
            .dt.days  # dt.days可以直接应用于序列 ,而不需要用apply
        )
    )
)


df_without_transfer_lsyz = (
    df_without_transfer_lsyz
    .assign(
        开抗生素时间为医嘱导出当天 = (
            df_without_transfer_lsyz
            .开抗生素时间与医嘱导出日期天数差 == 0
            # .apply(lambda x : True if x ==0 else False )   # 这里不需要apply,因为可以直接比较  
        )
    )
)


(
    df_without_transfer_lsyz
    .开抗生素时间为医嘱导出当天.value_counts()
)
False    1702
True      243
Name: 开抗生素时间为医嘱导出当天, dtype: int64
# 提取开抗生素时间为医嘱导出当天的行,这部分病人的抗生素才能计入当天

df_without_transfer_lsyz_eq_export_date = (
    df_without_transfer_lsyz
    .query('开抗生素时间为医嘱导出当天 == True')
)


df_without_transfer_lsyz_eq_export_date.频次.value_counts()
St      115
Qd       63
Bid      27
Q12h     19
Q8h      12
Tid       4
Qn        2
Q6h       1
Name: 频次, dtype: int64
无停嘱时间
# 停抗生素时间为空的行

df_without_transfer_lsyz_eq_export_date_without_stop_time  = (
    df_without_transfer_lsyz_eq_export_date
    .query('停抗生素时间.isna()')
    
)

df_without_transfer_lsyz_eq_export_date_without_stop_time.频次.value_counts()
St      111
Qd       62
Bid      26
Q12h     17
Q8h      12
Tid       4
Qn        2
Q6h       1
Name: 频次, dtype: int64
# 开医嘱时间所在的小时数

(
    df_without_transfer_lsyz_eq_export_date_without_stop_time
    .开抗生素时间
    .apply(lambda x : x.hour)   # 取时间的小时部分
    .value_counts()
    .reset_index(name = '计数')
    .rename(columns = {'index': '时'})  # 重命名索引列为 '小时'
)
计数
0 10 33
1 9 32
2 11 27
3 12 26
4 8 18
5 15 13
6 18 12
7 13 10
8 22 9
9 14 8
10 16 8
11 20 7
12 7 6
13 23 5
14 17 5
15 19 4
16 21 4
17 2 3
18 0 2
19 1 2
20 5 1
计算次数的规则
def calculate_use_count_without_transfer_lsyz_eq_export_date_without_stop_time(
    use_frequence : str,  # 使用频次代码
):
    if use_frequence.lower() in ['st', 'qd', 'prn', 'qn', '特殊间隔']:
        use_count = 1
    elif use_frequence.lower() in ['bid', 'q12h']:
        use_count = 2
    elif use_frequence.lower() in ['tid', 'q8h']:
        use_count = 3
    elif use_frequence.lower() in ['qid', 'q6h']:
        use_count = 4  
    else:
        use_count = 0
        print(f"calculate_use_count_without_transfer_lsyz_eq_export_date_without_stop_time:频次{use_frequence}没有映射次数!")

    return use_count
计算次数
df_without_transfer_lsyz_eq_export_date_without_stop_time = (
    df_without_transfer_lsyz_eq_export_date_without_stop_time
    .assign(
        实际使用次数 = df_without_transfer_lsyz_eq_export_date_without_stop_time
                        .频次.apply(calculate_use_count_without_transfer_lsyz_eq_export_date_without_stop_time)
    )
)

df_without_transfer_lsyz_eq_export_date_without_stop_time
入院时间 科室名称 病人姓名 住院号 床号 管床医生 抗生素名称 医嘱类型 抗生素医嘱 用量 单位 频次 开抗生素时间 停抗生素时间 转科信息 导出医嘱日期 开抗生素时间与医嘱导出日期天数差 开抗生素时间为医嘱导出当天 实际使用次数
0 2022-12-31 20:02:44.558 产科 蔡晨韵 620319 15 曾日明 (新福欣)注射用头孢呋辛钠#J 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(新福欣)注射用... 1.50 g Qd 2023-01-01 08:08:28.915 NaT NaN 2023-01-01 0 True 1
1 2022-12-31 20:02:44.558 产科 蔡晨韵 620319 15 曾日明 (新福欣)注射用头孢呋辛钠#J 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(新福欣)注射用... 0.75 g Q12h 2023-01-01 10:59:31.368 NaT NaN 2023-01-01 0 True 2
17 2022-12-30 15:34:16.729 产科 梁秦香 950148 19 曾日明 (新泰同)注射用头孢唑林钠#J 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(新泰同)注射用... 2.00 g Qd 2023-01-01 10:37:36.152 NaT NaN 2023-01-01 0 True 1
18 2022-12-30 15:34:16.729 产科 梁秦香 950148 19 曾日明 (新泰同)注射用头孢唑林钠#J 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(新泰同)注射用... 1.00 g Q12h 2023-01-01 18:02:08.267 NaT NaN 2023-01-01 0 True 2
23 2023-01-01 08:52:46.742 产科 廖心雨 950273 31 崔剑梅 (新泰同)注射用头孢唑林钠#J 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(新泰同)注射用... 1.00 g Q12h 2023-01-01 16:27:20.586 NaT NaN 2023-01-01 0 True 2
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
7348 2023-01-01 21:08:04.133 综合科 黎群芝 752600 16 崔秀美 (英贝齐)注射用头孢他啶#J 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(英贝齐)注射用... 1.00 g Qd 2023-01-01 22:03:46.291 NaT NaN 2023-01-01 0 True 1
7366 2022-12-29 13:48:30.269 综合科 梁期德 126715 15 崔秀美 (英贝齐)注射用头孢他啶#J 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(英贝齐)注射用... 1.00 g St 2023-01-01 18:47:42.935 NaT NaN 2023-01-01 0 True 1
7441 2022-12-31 16:19:24.194 综合科 郑连清 612549 17 崔秀美 (国产)注射用头孢曲松钠#(1g)J 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(国产)注射用头... 2.00 g St 2023-01-01 11:35:45.483 NaT NaN 2023-01-01 0 True 1
7488 2022-11-27 02:10:52.857 综合科特需病房 陈土胜 156664 15 钟雪华 (普立诃)左氧氟沙星氯化钠注射液J 临嘱 (普立诃)左氧氟沙星氯化钠注射液J 100ml:0.5g/袋 0.4g iv.drip Qd 0.40 g Qd 2023-01-01 23:33:14.123 NaT NaN 2023-01-01 0 True 1
7490 2023-01-01 17:14:48.136 综合科特需病房 宁彬汉 138918 20 代西艳 (国产)注射用头孢曲松钠#(1g)J 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(国产)注射用头... 2.00 g St 2023-01-01 17:52:51.876 NaT NaN 2023-01-01 0 True 1

235 rows × 19 columns

有停嘱时间
# 停抗生素时间不为空的行

df_without_transfer_lsyz_eq_export_date_with_stop_time = (
    df_without_transfer_lsyz_eq_export_date
    .query('停抗生素时间.notna()')
    
)

df_without_transfer_lsyz_eq_export_date_with_stop_time.频次.value_counts()
St      4
Q12h    2
Qd      1
Bid     1
Name: 频次, dtype: int64
计算次数的规则

有停抗生素时间,则说明该临嘱没有执行,无论停医嘱的时间与开医嘱时间的间隔是多少

计算次数
df_without_transfer_lsyz_eq_export_date_with_stop_time = (
    df_without_transfer_lsyz_eq_export_date_with_stop_time.
    assign(实际使用次数 = 0)
)

df_without_transfer_lsyz_eq_export_date_with_stop_time
入院时间 科室名称 病人姓名 住院号 床号 管床医生 抗生素名称 医嘱类型 抗生素医嘱 用量 单位 频次 开抗生素时间 停抗生素时间 转科信息 导出医嘱日期 开抗生素时间与医嘱导出日期天数差 开抗生素时间为医嘱导出当天 实际使用次数
45 2022-12-28 12:53:50.354 产科 谢思燕 949900 20 陈顺娣 (新泰同)注射用头孢唑林钠#J 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(新泰同)注射用... 1.0 g Q12h 2023-01-01 20:17:44.439 2023-01-01 22:08:43.548 NaN 2023-01-01 0 True 0
198 2023-01-01 10:48:36.224 儿科 洪颢铭 950295 73 徐世裕 (国产)注射用头孢曲松钠#(1g)J 临嘱 (国产)注射用头孢曲松钠#(1g)J 1g/支 0.7g|5%葡萄糖注射液(50ml) 5%... 0.7 g St 2023-01-01 11:42:45.875 2023-01-01 12:29:00.514 NaN 2023-01-01 0 True 0
2262 2023-01-01 13:00:16.367 全科医学科 刘玉兰 581111 009 雷夏燕 注射用头孢西丁钠(1g) 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|注射用头孢西丁钠... 2.0 g Q12h 2023-01-01 15:38:22.537 2023-01-01 15:43:32.003 NaN 2023-01-01 0 True 0
4295 2022-12-26 11:51:29.622 肾内二科 杨木森 922954 018 戴妙飞 (英贝齐)注射用头孢他啶#J 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(英贝齐)注射用... 1.0 g Qd 2023-01-01 02:15:06.943 2023-01-01 08:17:56.377 NaN 2023-01-01 0 True 0
6087 2023-01-01 12:52:31.043 血液风湿科 李江霞 938783 61 黎春华 氟康唑片#J 临嘱 氟康唑片#J 50mg*24片/盒 200mg P.O Bid 200.0 mg Bid 2023-01-01 13:07:19.334 2023-01-01 14:38:34.133 NaN 2023-01-01 0 True 0
6122 2022-12-24 16:54:15.143 血液风湿科 刘惠英 748778 38 吴晓鸿 注射用伏立康唑(迪尔达宁0.2g) 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|注射用伏立康唑(... 0.2 g St 2023-01-01 23:39:16.441 2023-01-01 23:41:53.779 NaN 2023-01-01 0 True 0
7106 2023-01-01 14:00:53.759 重症医学科三区 梁丽珍 950308 01 余锋尤 (石四药)盐酸莫西沙星氯化钠注射液#J 临嘱 (石四药)盐酸莫西沙星氯化钠注射液#J 250ml/袋(0.4g:2g) 250ml iv.... 250.0 ml St 2023-01-01 15:35:10.360 2023-01-01 20:59:18.623 NaN 2023-01-01 0 True 0
7214 2023-01-01 21:07:33.960 重症医学科五区 柯月梅 745360 006 李富起 (国产)注射用头孢曲松钠#(1g)J 临嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(国产)注射用头... 2.0 g St 2023-01-01 22:19:09.725 2023-01-01 23:52:14.998 NaN 2023-01-01 0 True 0

62.3.5.2 长嘱部分

# 无转科信息病人的长嘱

df_without_transfer_cqyz = (
    df_without_transfer.query('医嘱类型=="长嘱"')
)

print(df_without_transfer_cqyz.shape)

df_without_transfer_cqyz.频次.value_counts()
(1294, 16)
Qd      449
Q8h     414
Q12h    320
Q6h      59
Bid      40
Tid       9
Qn        2
Qod       1
Name: 频次, dtype: int64
df_without_transfer_cqyz = (
    df_without_transfer_cqyz
    .assign(
        开抗生素时间与医嘱导出日期天数差 = (
            lambda x : (x.开抗生素时间 - x.导出医嘱日期).apply(lambda x : x.days) 
        )
    )
    .assign(
        开抗生素时间早于医嘱导出当天 = lambda x : x.开抗生素时间与医嘱导出日期天数差.apply(lambda x : True if x < 0 else False)
    )   # 当天的长嘱需要从临嘱开药发药,故当天的长嘱不计入
    )
    

df_without_transfer_cqyz.开抗生素时间早于医嘱导出当天.value_counts()
True     935
False    359
Name: 开抗生素时间早于医嘱导出当天, dtype: int64
# 提取开抗生素时间早于导出当天的行,这部分病人的抗生素才能计入当天
# 当天的长嘱需要从临嘱开药发药,故当天的长嘱不计入

df_without_transfer_cqyz_lt_export_date = (
    df_without_transfer_cqyz
    .query('开抗生素时间早于医嘱导出当天 == True')
)

df_without_transfer_cqyz_lt_export_date.head()
入院时间 科室名称 病人姓名 住院号 床号 管床医生 抗生素名称 医嘱类型 抗生素医嘱 用量 单位 频次 开抗生素时间 停抗生素时间 转科信息 导出医嘱日期 开抗生素时间与医嘱导出日期天数差 开抗生素时间早于医嘱导出当天
56 2022-12-31 17:52:51.788 创伤骨科 车广南 704184 053 徐海乔 (进口)注射用头孢曲松钠(0.5g)# 长嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(进口)注射用头... 1.0 g Qd 2022-12-31 18:29:23.108 NaT NaN 2023-01-01 -1 True
63 2022-12-08 20:25:45.957 创伤骨科 陈治朴 947922 069 李伟雄 (左克)盐酸左氧氟沙星注射液 长嘱 0.9%氯化钠注射液#(250ml) 0.9%*250ml/袋 250ml|(左克)盐酸左氧... 0.3 g Qd 2022-12-13 21:26:26.976 2022-12-15 11:37:42.667 NaN 2023-01-01 -19 True
64 2022-12-08 20:25:45.957 创伤骨科 陈治朴 947922 069 李伟雄 (左克)盐酸左氧氟沙星注射液 长嘱 0.9%氯化钠注射液#(250ml) 0.9%*250ml/袋 250ml|(左克)盐酸左氧... 0.3 g Qd 2022-12-15 11:31:27.116 2022-12-26 09:07:47.666 NaN 2023-01-01 -17 True
66 2022-12-08 20:25:45.957 创伤骨科 陈治朴 947922 069 李伟雄 (左克)盐酸左氧氟沙星注射液 长嘱 0.9%氯化钠注射液#(250ml) 0.9%*250ml/袋 250ml|(左克)盐酸左氧... 0.3 g Qd 2022-12-27 22:04:35.229 NaT NaN 2023-01-01 -5 True
112 2022-12-21 16:32:23.291 创伤骨科 梁邦俊 461234 055 李伟雄 (特治星)注射用哌拉西林钠他唑巴坦钠#(4.5g) 长嘱 (特治星)注射用哌拉西林钠他唑巴坦钠#(4.5g) 4.5g/支 4.5g|0.9%氯化钠注... 4.5 g Q8h 2022-12-23 10:34:39.204 2022-12-24 09:50:21.849 NaN 2023-01-01 -9 True
无停嘱时间
df_without_transfer_cqyz_lt_export_date_without_stoptime = (
    df_without_transfer_cqyz_lt_export_date
    .query('停抗生素时间.isna()')
)

df_without_transfer_cqyz_lt_export_date_without_stoptime.频次.value_counts()
Qd      134
Q8h     104
Q12h     98
Q6h      22
Bid      11
Tid       5
Name: 频次, dtype: int64
计算次数的规则
# 没有停嘱时间,则认为当天长嘱全部执行完

def calculate_use_count_without_transfer_cqyz_lt_export_date_without_stoptime(
    use_frequence : str,  # 使用频次代码
):
    use_frequence = use_frequence.lower()
    
    if use_frequence in ['qd', 'qn']:
        use_count = 1
    elif use_frequence in ['bid', 'q12h']:
        use_count = 2
    elif use_frequence in ['tid', 'q8h']:
        use_count = 3
    elif use_frequence in ['qid', 'q6h']:
        use_count = 4  
    else:
        use_count = 0
        print(f"calculate_use_count_without_transfer_lsyz_eq_export_date_without_stop_time:频次{use_frequence}没有映射次数!")

    return use_count
计算次数
df_without_transfer_cqyz_lt_export_date_without_stoptime = (
    df_without_transfer_cqyz_lt_export_date_without_stoptime
    .assign(
        实际使用次数 = lambda x : x.频次.apply(calculate_use_count_without_transfer_cqyz_lt_export_date_without_stoptime)
    )
)

df_without_transfer_cqyz_lt_export_date_without_stoptime.head()
入院时间 科室名称 病人姓名 住院号 床号 管床医生 抗生素名称 医嘱类型 抗生素医嘱 用量 单位 频次 开抗生素时间 停抗生素时间 转科信息 导出医嘱日期 开抗生素时间与医嘱导出日期天数差 开抗生素时间早于医嘱导出当天 实际使用次数
56 2022-12-31 17:52:51.788 创伤骨科 车广南 704184 053 徐海乔 (进口)注射用头孢曲松钠(0.5g)# 长嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(进口)注射用头... 1.00 g Qd 2022-12-31 18:29:23.108 NaT NaN 2023-01-01 -1 True 1
66 2022-12-08 20:25:45.957 创伤骨科 陈治朴 947922 069 李伟雄 (左克)盐酸左氧氟沙星注射液 长嘱 0.9%氯化钠注射液#(250ml) 0.9%*250ml/袋 250ml|(左克)盐酸左氧... 0.30 g Qd 2022-12-27 22:04:35.229 NaT NaN 2023-01-01 -5 True 1
169 2022-12-15 21:45:53.290 儿科 陈俊涛 948703 U03 汤韶斌 注射用亚胺培南-西司他丁钠(1g) 长嘱 注射用亚胺培南-西司他丁钠(1g) 1g/支 2g 其他 Qd 拿药 2.00 g Qd 2022-12-23 10:42:14.559 NaT NaN 2023-01-01 -9 True 1
170 2022-12-15 21:45:53.290 儿科 陈俊涛 948703 U03 汤韶斌 注射用万古霉素(稳可信) 长嘱 注射用万古霉素(稳可信) 0.5g/支 1g 其他 Qd 拿药 1.00 g Qd 2022-12-23 10:44:41.380 NaT NaN 2023-01-01 -9 True 1
171 2022-12-15 21:45:53.290 儿科 陈俊涛 948703 U03 汤韶斌 注射用亚胺培南-西司他丁钠(1g) 长嘱 5%葡萄糖注射液#(100ml) 5%*100ml/袋 80ml|注射用亚胺培南-西司他丁钠... 0.48 g Q6h 2022-12-23 10:46:25.628 NaT NaN 2023-01-01 -9 True 4
有停嘱时间
df_without_transfer_cqyz_lt_export_date_with_stoptime = (
    df_without_transfer_cqyz_lt_export_date
    .query('停抗生素时间.notna()')
)


## 确认停嘱时间与导出当天的关系,

df_without_transfer_cqyz_lt_export_date_with_stoptime = (
    df_without_transfer_cqyz_lt_export_date_with_stoptime
    .assign(
        停抗生素时间与医嘱导出日期天数差 = (
            lambda x : (x.停抗生素时间 - x.导出医嘱日期).apply(lambda x : x.days) 
        )
    )
    )

df_without_transfer_cqyz_lt_export_date_with_stoptime.停抗生素时间与医嘱导出日期天数差.value_counts()
-1      65
 0      59
 1      53
-3      48
-2      43
        ..
-59      1
-131     1
-108     1
-92      1
-122     1
Name: 停抗生素时间与医嘱导出日期天数差, Length: 65, dtype: int64
计算次数的规则与计算次数
# 情况一: 停抗生素时间与医嘱导出日期天数差小于0,即停医嘱时间早于医嘱导出日期,实际使用次数为0,


df_without_transfer_cqyz_lt_export_date_with_stoptime.loc[
    df_without_transfer_cqyz_lt_export_date_with_stoptime.停抗生素时间与医嘱导出日期天数差 < 0,
    '实际使用次数'
] = 0


# 情况二: 停抗生素时间与医嘱导出日期天数差大于0(回顾性导出的医嘱),即停医嘱时间晚于医嘱导出日期,实际使用次数按照无停嘱时间的规则来算,


df_without_transfer_cqyz_lt_export_date_with_stoptime.loc[
    df_without_transfer_cqyz_lt_export_date_with_stoptime.停抗生素时间与医嘱导出日期天数差 > 0,
    '实际使用次数'
] = (
    df_without_transfer_cqyz_lt_export_date_with_stoptime
    .loc[
        df_without_transfer_cqyz_lt_export_date_with_stoptime.停抗生素时间与医嘱导出日期天数差 > 0,
        '频次'
    ]
    .apply(calculate_use_count_without_transfer_cqyz_lt_export_date_without_stoptime) # 实际使用次数按照无停嘱时间的规则来算,
)


# 情况三: 停抗生素时间与医嘱导出日期天数差等于0),即医嘱导出当天停的长嘱,实际使用次数按照以下规则来算


# 如果是qd默认为已执行,qn默认为未执行
# 非qd的情况,则为停嘱时间减去医嘱导出当天零时,除以频次代表的间隔小时数,取整数部分即为使用次数


frequency_interval_hours_dict = {
    'qod': 48,
    'qd' : 24,
    'qn' : 24,
    'q12h': 12,
    'bid': 12,
    'q8h' : 8,
    'tid': 8,
    'q6h': 6,
    'qid': 6
}


def calculate_use_count_without_transfer_cqyz_lt_export_date_with_stoptime_at_export_date(
    use_frequence : str,  # 使用频次代码,
    elapse_hour: int   # 从当天零时到停医嘱时间过去的小时数,即为停医嘱时间的小时部分
):
    use_frequence = use_frequence.lower()
    if use_frequence in ['qd', 'qn']:
        use_count = 1
    else:
        frequency_interval_hours = frequency_interval_hours_dict.get(use_frequence, None)
        if frequency_interval_hours:
            use_count = elapse_hour // frequency_interval_hours  # 取整数部分
        else:
            use_count = 0
            print(f"calculate_use_count_without_transfer_cqyz_lt_export_date_with_stoptime_at_export_date:\
            频次{use_frequence}没有映射间隔小时数!")

    return use_count


df_without_transfer_cqyz_lt_export_date_with_stoptime.loc[
    df_without_transfer_cqyz_lt_export_date_with_stoptime.停抗生素时间与医嘱导出日期天数差 == 0,
    '实际使用次数'
] = (
    df_without_transfer_cqyz_lt_export_date_with_stoptime
    .loc[
        df_without_transfer_cqyz_lt_export_date_with_stoptime.停抗生素时间与医嘱导出日期天数差 == 0,
        ['频次', '停抗生素时间']
    ]
    .apply(
        lambda row : calculate_use_count_without_transfer_cqyz_lt_export_date_with_stoptime_at_export_date(
            row['频次'], row['停抗生素时间'].hour
        ),
        axis = 1  # 在行上应用函数
    ) # 实际使用次数按照无停嘱时间的规则来算,
)




(
    df_without_transfer_cqyz_lt_export_date_with_stoptime
    .query('停抗生素时间与医嘱导出日期天数差 == 0')
    .head()
)
入院时间 科室名称 病人姓名 住院号 床号 管床医生 抗生素名称 医嘱类型 抗生素医嘱 用量 单位 频次 开抗生素时间 停抗生素时间 转科信息 导出医嘱日期 开抗生素时间与医嘱导出日期天数差 开抗生素时间早于医嘱导出当天 停抗生素时间与医嘱导出日期天数差 实际使用次数
115 2022-12-21 16:32:23.291 创伤骨科 梁邦俊 461234 055 李伟雄 (特治星)注射用哌拉西林钠他唑巴坦钠#(4.5g) 长嘱 (特治星)注射用哌拉西林钠他唑巴坦钠#(4.5g) 4.5g/支 4.5g|0.9%氯化钠注... 4.500 g Q8h 2022-12-24 09:43:08.177 2023-01-01 09:41:30.971 NaN 2023-01-01 -8 True 0 1.0
167 2022-12-15 21:45:53.290 儿科 陈俊涛 948703 U03 汤韶斌 (国产)注射用头孢曲松钠#(1g)J 长嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(国产)注射用头... 1.000 g Qd 2022-12-15 22:26:36.613 2023-01-01 10:37:00.077 NaN 2023-01-01 -17 True 0 1.0
268 2022-12-21 17:57:33.323 儿科 徐康棋 949240 58 李超 阿奇霉素片#(0.25g)J 长嘱 阿奇霉素片#(0.25g)J 0.25g*6片/盒 0.375g P.O Qd 0.375 g Qd 2022-12-27 07:44:06.594 2023-01-01 09:35:48.895 NaN 2023-01-01 -5 True 0 1.0
598 2022-12-22 21:30:37.771 肝胆胰肛肠外科 张国颖 600838 029 王仕佳 注射用头孢西丁钠(1g) 长嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|注射用头孢西丁钠... 1.000 g Q12h 2022-12-23 14:24:36.467 2023-01-01 10:15:55.106 NaN 2023-01-01 -9 True 0 0.0
621 2022-12-29 20:28:17.195 感染科 车桂芳 419697 26 黄东良 (国产)注射用头孢曲松钠#(1g)J 长嘱 0.9%氯化钠注射液#(100ml) 0.9%*100ml/袋 100ml|(国产)注射用头... 1.000 g Qd 2022-12-29 21:22:34.879 2023-01-01 12:32:17.618 NaN 2023-01-01 -3 True 0 1.0

62.3.6 转科信息不全为空的行

指开了抗生素的病人

# 提取转科信息不全为空的病人(即存在转科)

df_with_transfer = (
    df_with_antibiotics
    .groupby('住院号')
    .filter(lambda group : ~group['转科信息'].isna().all())   # 每个病人作为一组,转科信息是否不全为空
    
)

df_with_transfer.转科信息 = df_with_transfer.转科信息.str.replace("神经内一科", "神经内科一区")


df_with_transfer.住院号.unique().shape
(278,)

62.3.6.1 提取转科信息并判断抗生素的归属

提取一一对应的入科时间和入科科室
比导出医嘱日期(设定为当日的23:59:59)早,且最接近导出医嘱日期的那个入科日期对应的科室,为抗生素医嘱真正归属的科室

def attribute_antibiotic_department(
    dept_name: str,  # 科室名称
    export_date,     # 导出医嘱日期
    transfer_info    # 转科信息
):
    transfer_time_dept = re.findall(r"(\d+年\d+月\d+日\d+时\d+分)\s+转往\s+(.*?)\s+", transfer_info)

    # 加上时间部分,组成当日最晚时间
    export_date = pd.Timestamp.combine(export_date, pd.Timestamp('23:59:59').time())  # 时间部分

    
    # 将结果转换为字典,键为时间,值为科室
    transfer_dict = {
        (export_date - pd.to_datetime(
            transfer_time, 
            format = "%Y年%m月%d日%H时%M分")
        ).days: transfer_in_dept for transfer_time, transfer_in_dept in transfer_time_dept
    }

   
    # 导出所有为正值的天数
    export_transfer_date_diff_positive =  [export_transfer_date_diff_ele 
         for export_transfer_date_diff_ele in transfer_dict.keys() \
         if export_transfer_date_diff_ele >=0]

    
    if export_transfer_date_diff_positive:
        export_transfer_date_diff_positive_min = min(export_transfer_date_diff_positive)
        attributed_dept = transfer_dict.get(export_transfer_date_diff_positive_min)
        # if attributed_dept != dept_name:
        #     print(f"导出医嘱科室为{dept_name},实际上为医嘱发生在:{attributed_dept},转科信息: {transfer_info}")
    else:  # 全部为负数
        attributed_dept = dept_name
    
    
        

    return attributed_dept
    

df_with_transfer = (
    df_with_transfer
    .assign(
        抗生素归属科室 = lambda x: x.apply(
            lambda row: attribute_antibiotic_department(
                row['科室名称'], row['导出医嘱日期'], row['转科信息']), axis=1)
    ,
        # 或者采取以下写法
       # 抗生素归属科室 = df_with_transfer[['科室名称', '导出医嘱日期', '转科信息']].apply(
       #      lambda row: attribute_antibiotic_department(
       #          row['科室名称'], row['导出医嘱日期'], row['转科信息']), axis=1)
   )
)

62.3.6.2 修正科室名称

(
    df_with_transfer
    .loc[
        df_with_transfer.科室名称 != df_with_transfer.抗生素归属科室, 
        '科室名称'
    ] 
) = (
    df_with_transfer
    .loc[
         df_with_transfer.科室名称 != df_with_transfer.抗生素归属科室, 
        '抗生素归属科室'
    ]
)


df_with_transfer.query('科室名称 != 抗生素归属科室')
入院时间 科室名称 病人姓名 住院号 床号 管床医生 抗生素名称 医嘱类型 抗生素医嘱 用量 单位 频次 开抗生素时间 停抗生素时间 转科信息 导出医嘱日期 抗生素归属科室

62.3.6.3 按照转科信息全为空的方法处理

详见业务流程图

62.3.7 合并各个部分的数据

每次计算次数得到的数据框
删除实际使用次数为0

62.4 打包成函数