欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

武汉加油,中国加油--全国新型肺炎R0计算记录

程序员文章站 2024-03-25 21:44:46
...

武汉加油,中国加油

基本再生数

**基本再生数(basic reproduction number,R0)**是指在一个全是易感染态个体构成的群体中,一个感染态的个体在恢复之前平均能感染的人数。在流行病学中,R0>1 表示疾病将爆发,<1 则表示疾病走向消亡,故 R0 是判断流行病是否爆发的重要条件之一。但在真实疫情的传播过程中,由于*干预政策实施、个体行为改变(戴口罩、减少出行等)、易感人群数量减少(因患病人数增多或使用疫苗等)等外在因素影响,不再满足基本再生数定义的理想模型条件。为刻画流行病随时间的演化过程,我们将传播过程中某一时刻下(t)平均一个感染态个体感染的人数定义为有效再生数,记为 Rt。在实际疫情的控制过程中,当 Rt<1 时,即平均一个感染态个体感染的人数小于 1 时,认为疾病已被控制同时疾病也将走向消亡。

相关论文

武汉新型冠状病毒感染肺炎基本再生数的初步预测
论文地址:http://www.cjebm.com/article/10.7507/1672-2531.202001118
对源自中国武汉的2019-nCoV爆发的潜在国内和国际传播的预测和预测:一项模型研究
论文地址:ttps://www.thelancet.com/journals/lancet/article/PIIS0140-6736(20)30260-9/fulltext
武汉市2019例新型冠状病毒性肺炎99例流行病学和临床特征
论文地址:https://www.thelancet.com/journals/lancet/article/PIIS0140-6736(20)30211-7/fulltext
与2019年新型冠状病毒相关的家族性肺炎,表明人与人之间的传播:家庭聚类研究
论文地址:https://www.thelancet.com/journals/lancet/article/PIIS0140-6736(20)30154-9/fulltext
中国武汉市2019年新型冠状病毒感染患者的临床特征
论文地址:https://www.thelancet.com/journals/lancet/article/PIIS0140-6736(20)30183-5/fulltext

数据来源

https://voice.baidu.com/act/newpneumonia/newpneumonia/?from=osari_pc_3
以及每日深圳公布的详细感染病例

代码部分

# from login.mysql_login import conn as CONN
import pandas as pd,numpy as np
import math,datetime




if __name__ == '__main__':
    # sp_ncov_status_all = pd.read_sql('''
    # select  occur_period_f,
    #         admin_area_name,
    #         confirm as '确诊病例(人)',
    #         cure as '治愈人数(人)',
    #         death as '死亡人数(人)',
    #         suspect as '疑似病例(人)'
    # from qhdata_support_spider.sp_ncov_status
    # WHERE admin_area_code = 0086
    # ORDER BY occur_period_f
    # ''',CONN)
    #
    # sp_ncov_status_sz = pd.read_sql('''
    # select occur_period_f,
    #        admin_area_name,
    #        confirm as '确诊病例(人)',
    #        cure as '治愈人数(人)',
    #        death as '死亡人数(人)',
    #        suspect as '疑似病例(人)'
    # from qhdata_support_spider.sp_ncov_status
    # WHERE admin_area_code = 440300000000
    #     ''', CONN)

    sp_ncov_status_all = pd.read_excel('source/sp_ncov_status_all.xlsx')
    sp_ncov_status_sz = pd.read_excel('source/sp_ncov_status_sz.xlsx')
    detail_case = pd.read_excel('source/深圳市冠状病毒病例个案数据(汇总)-20200206.xlsx')

    # ##############################数据预处理##############################################
    for i in ['确诊病例(人)','治愈人数(人)','死亡人数(人)']:
    #     sp_ncov_status_all['当日' + i] = sp_ncov_status_all[i] - sp_ncov_status_all[i].shift()
        sp_ncov_status_sz['当日' + i] = sp_ncov_status_sz[i] - sp_ncov_status_sz[i].shift()

    detail_case['疑似到确诊时间间隔'] = detail_case[['发病时间','确诊时间']].\
        apply(lambda x:None if x[0] == '-' else
                       None if x[1] == '-' else
                       (x[1] - x[0]).days,
              axis=1)
    detail_case['疑似到确诊时间间隔'] = detail_case['疑似到确诊时间间隔'].apply(lambda x:None if x < 0 else x)
    detail_case['年龄'] = detail_case['年龄'].astype(int)

    # 以第一个不明原因肺炎发现者的报道时间2019年12月8日为感染的第一天
    first_date = datetime.datetime.strptime('2019-12-08', "%Y-%m-%d")
    sp_ncov_status_all['t'] = sp_ncov_status_all['occur_period_f'].apply(lambda x:(datetime.datetime.strptime(x, "%Y-%m-%d") - first_date).days + 1)

    # #####################################################################################
    # ##############################数据统计################################################
    case_num = detail_case.shape[0]
    # 性别比例
    sex_info = pd.pivot_table(detail_case,
                   index=['性别'],
                   values=['病例序号'],
                   aggfunc={'病例序号': [len,lambda x:len(x)/case_num]}).reset_index()
    sex_info.columns = ['性别','占比','人数']
    # 年龄分层
    temp_df = detail_case[['年龄','病例序号']]
    temp_df['年龄分组'] = temp_df.年龄.apply(lambda x:'1.青少幼年(20以下)' if x < 20 else
                                                     '2.青壮年(20-50)' if ((x >= 20) and (x < 50)) else
                                                     '3.中年(50-70)' if ((x >= 50) and (x < 70)) else
                                                     '4.老年(70以上)'
                                            )
    age_info =temp_df[['年龄分组','病例序号']].\
        groupby('年龄分组').\
        agg({'病例序号':[len,lambda x:len(x)/case_num]}).reset_index()
    age_info.columns = ['年龄分组','人数','占比']
    # 疑似到确诊时间间隔
    diagnostic_interval = pd.DataFrame(detail_case.describe()['疑似到确诊时间间隔']).T
    diagnostic_interval_1 = pd.pivot_table(detail_case,
                   index=['疑似到确诊时间间隔'],
                   values=['病例序号'],
                   aggfunc={'病例序号': [len,lambda x:len(x)/case_num]}).reset_index()
    diagnostic_interval_1.columns = ['疑似到确诊时间间隔','占比','人数']
    # #####################################################################################
    # ##############################计算逻辑################################################
    avg_day = diagnostic_interval['mean'][0].round(2) # 疑似到确诊时间间隔引用深圳市的平均值(天)
    # 选择拥有新增最新数据的2.4-2.6日的确认数据与对应的2.1-2.3疑似数据(相隔4天左右),计算转化率p
    p = round((3887 + 3694 + 3151) / (4562 + 5173 + 5072), 2)
    # SARS传播的p的取值在0.5-0.8之间;初期报导提到59个疑似病例有41位最终确诊,因此p的一个参考值为41/59=0.695;
    # 以第一个不明原因肺炎发现者的报道时间2019年12月8日为t=1
    # 2020年2月6日实际上被感染人数为Y(t),t=61
    Y_t = 3151 + round(4833*p,0)
    t = 61
    T_g  = 8.4# 生成时间(generation time)
    lamda = math.log(Y_t,math.e)/t
    Rho = (T_g - avg_day)/T_g # 潜伏期占生成时间的比例Rho
    R_0 = 1 + lamda*T_g + Rho*(1 - Rho) * math.pow((lamda*T_g),2)
    # #####################################################################################
    # ##############################数据计算################################################
    def basicReproductionNumber(Y_t,t,avg_day,T_g  = 8.4):
        lamda = math.log(Y_t,math.e)/t
        Rho = (T_g - avg_day) / T_g  # 潜伏期占生成时间的比例Rho
        R_0 = 1 + lamda * T_g + Rho * (1 - Rho) * math.pow((lamda * T_g), 2)
        return R_0

    sp_ncov_status_all_temp = sp_ncov_status_all.dropna()
    sp_ncov_status_all_temp['Y_t'] = sp_ncov_status_all_temp['新增确诊(人)'] + sp_ncov_status_all_temp['新增疑似(人)'] * p
    sp_ncov_status_all_temp['Y_t'] = sp_ncov_status_all_temp['Y_t'].round(0)

    sp_ncov_status_all_temp['R0'] = sp_ncov_status_all_temp[['Y_t','t']].\
        apply(lambda x:basicReproductionNumber(x[0],x[1],avg_day,8.4),axis=1)
    # #####################################################################################
    # ##############################画图###################################################
    import matplotlib.pyplot as plt
    import seaborn as sns
    plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
    plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

    fig = plt.figure(figsize=[16, 9])  # 设定图片大小
    temp_df = age_info[['年龄分组','人数']]
    sns.barplot(x='年龄分组', y='人数',data=temp_df[['年龄分组','人数']])
    plt.savefig('pic/年龄分层.png')
    plt.close()

    fig = plt.figure(figsize=[16, 9])  # 设定图片大小
    ax1 = fig.add_subplot(111)  # 添加第一副图
    ax2 = ax1.twinx()  # 共享x轴,这句很关键!
    sns.barplot(x='性别', y='人数', data=sex_info[['性别','人数']], ax=ax1, alpha=0.8)  # 画柱状图,注意ax是选择画布
    sns.pointplot(x='性别', y='占比', data=sex_info[['性别','占比']], ax=ax2)  # 画在ax2画布上
    plt.savefig('pic/性别比例.png')
    # plt.show()
    plt.close(fig)

    fig = plt.figure(figsize=[16, 9])  # 设定图片大小
    temp_df = diagnostic_interval_1[['疑似到确诊时间间隔','人数']]
    sns.barplot(x='疑似到确诊时间间隔', y='人数',data=temp_df[['疑似到确诊时间间隔','人数']])
    plt.savefig('pic/疑似到确诊时间间隔.png')
    plt.close()

    fig = plt.figure(figsize=[16, 9])  # 设定图片大小
    temp_df = sp_ncov_status_all_temp[['occur_period_f', 'R0']]
    sns.pointplot(x='occur_period_f', y='R0',data=temp_df)
    plt.savefig('pic/R0变化趋势.png')
    plt.close()

# #####################################################################################

部分说明

1.计算公式的来由:
中国循证医学杂志的《武汉新型冠状病毒感染肺炎基本再生数的初步预测》
柳叶刀的《Nowcasting and forecasting the potential domestic and
international spread of the 2019-nCoV outbreak originating
in Wuhan, China: a modelling study》
武汉加油,中国加油--全国新型肺炎R0计算记录
武汉加油,中国加油--全国新型肺炎R0计算记录
2.Tg的来由:
柳叶刀的《A familial cluster of pneumonia associated with the 2019
novel coronavirus indicating person-to-person transmission:
a study of a family cluster》
武汉加油,中国加油--全国新型肺炎R0计算记录
红框是没有去武汉的深圳一家人中的一人,从中可以看出,该人在其他家庭成员回来后大约经过8.4天后发病。出现初步症状是在8号左右。

结果展示

年龄分组
武汉加油,中国加油--全国新型肺炎R0计算记录
性别分组
武汉加油,中国加油--全国新型肺炎R0计算记录
疑似到确诊时间间隔分布
武汉加油,中国加油--全国新型肺炎R0计算记录
R0变化趋势
武汉加油,中国加油--全国新型肺炎R0计算记录