新闻  |   论坛  |   博客  |   在线研讨会
实现病人数据自动分析建模,Python能做的比你想象得更多
AI科技大本营 | 2020-12-21 11:29:23    阅读:750   发布文章

数据表格整理等作为我们工作学习生活中最为繁琐和无趣的任务之一,消耗掉了我们的大多数时间。而今天我们就将利用Python对病人数据进行建模,并自动生成表单,从而节省了我们医务工作者的大量时间。

最终生成的表单数据如下可见,每个病人分别以单独的Word表单保存,一键分析Excel数据,生成表单,并自动给出病人具体的评估。                           

5.jpg

实验前的准备

首先我们使用的Python版本是3.6.5所用到的模块如下:

·  openpyxl库用来读取Excel表格数据。

·  datetime模块用来对时间处理和生成。

·  Docx库即为Python-docx包,这是一个很强大的包,可以用来创建docx文档,包含段落、分页符、表格、图片、标题、样式等几乎所有的Word文档中能常用的功能都包含了,这个包的主要功能便是用来创建文档。

下面我们需要将需要处理的数据文件放到同一目录下,部分文件数据如下图:

4.jpg

其中需要用到的文件命名为data.xlsx。

表格生成

我们需要生成的固定项如下表所见:

3.jpg

即主要包括项目名称、评估内容、评估结果和评估定级。

部分代码如下:

'''填写单元格'''

table.cell(0, 0).merge(table.cell(1, 0))  # 合并单元格

table.cell(0, 0).text = "项目"

table.cell(0, 0).paragraphs[0].runs[0].font.bold = True # 加粗

table.cell(0, 0).paragraphs[0].runs[0].font.size = Pt(12)  # 字号大小

table.cell(0, 0).vertical_alignment = WD_ALIGN_VERTICAL.CENTER  # 垂直居中

table.cell(0, 0).paragraphs[0].paragraph_format.alignment= WD_ALIGN_PARAGRAPH.CENTER  # 水平居中

table.cell(0, 1).merge(table.cell(1, 1))  # 合并单元格

table.cell(0, 1).text = "评估内容"

table.cell(0, 1).paragraphs[0].runs[0].font.bold = True # 加粗

table.cell(0, 1).paragraphs[0].runs[0].font.size = Pt(12)  # 字号大小

table.cell(0, 1).vertical_alignment = WD_ALIGN_VERTICAL.CENTER  # 垂直居中

table.cell(0, 1).paragraphs[0].paragraph_format.alignment= WD_ALIGN_PARAGRAPH.CENTER  # 水平居中

table.cell(0, 2).merge(table.cell(1, 2))  # 合并单元格

table.cell(0, 2).text = "评估结果"

table.cell(0, 2).paragraphs[0].runs[0].font.bold = True # 加粗

table.cell(0, 2).paragraphs[0].runs[0].font.size = Pt(12)  # 字号大小

table.cell(0, 2).vertical_alignment = WD_ALIGN_VERTICAL.CENTER  # 垂直居中

table.cell(0, 2).paragraphs[0].paragraph_format.alignment= WD_ALIGN_PARAGRAPH.CENTER  # 水平居中

table.cell(0, 3).merge(table.cell(0, 5))  # 合并单元格

table.cell(0, 3).text = "评估定级"

table.cell(0, 3).paragraphs[0].runs[0].font.bold = True # 加粗

table.cell(0, 3).paragraphs[0].runs[0].font.size = Pt(12)  # 字号大小

table.cell(0, 3).vertical_alignment = WD_ALIGN_VERTICAL.CENTER  # 垂直居中

table.cell(0, 3).paragraphs[0].paragraph_format.alignment= WD_ALIGN_PARAGRAPH.CENTER  # 水平居中

table.cell(1, 3).text = "良好"

table.cell(1, 3).paragraphs[0].runs[0].font.bold = True # 加粗

table.cell(1, 3).paragraphs[0].runs[0].font.size = Pt(12)  # 字号大小

table.cell(1, 3).vertical_alignment = WD_ALIGN_VERTICAL.CENTER  # 垂直居中

table.cell(1, 3).paragraphs[0].paragraph_format.alignment= WD_ALIGN_PARAGRAPH.CENTER  # 水平居中

table.cell(1, 4).text = "中等"

table.cell(1, 4).paragraphs[0].runs[0].font.bold = True # 加粗

table.cell(1, 4).paragraphs[0].runs[0].font.size = Pt(12)  # 字号大小

table.cell(1, 4).vertical_alignment = WD_ALIGN_VERTICAL.CENTER  # 垂直居中

table.cell(1, 4).paragraphs[0].paragraph_format.alignment= WD_ALIGN_PARAGRAPH.CENTER  # 水平居中

table.cell(1, 5).text = "中等"

table.cell(1, 5).paragraphs[0].runs[0].font.bold = True # 加粗

table.cell(1, 5).paragraphs[0].runs[0].font.size = Pt(12)  # 字号大小

table.cell(1, 5).vertical_alignment = WD_ALIGN_VERTICAL.CENTER  # 垂直居中

table.cell(1, 5).paragraphs[0].paragraph_format.alignment=

数据计算与匹配整合

(1)数据清洗:

首先要读取数据,其中包括数据的清洗,即Excel日期数据和标准日期格式不匹配的问题,需要使用datetime转成标准时间:

workbook = load_workbook(u'./data.xlsx')    #找到需要xlsx文件的位置

booksheet = workbook.active                #获取当前活跃的sheet,默认是第一个sheet

rows = booksheet.rows

index=None

for row in rows:

    index = [col.value for col in row]

    break

dct = {j:i for i,j in enumerate(index)}

for i,row in enumerate(rows):

    #一个人的资料

    one_person =[col.value for col in row]

    #计算年龄

    birth=one_person[dct['bd']]

    age=None

    #now设置为问卷调查的日期

    now =datetime.date(2020,7,15)

    if now.month < birth.month:

        age = now.year - birth.year - 1

    if now.month > birth.month:

        age = now.year - birth.year

    if now.month == birth.month and now.day <birth.day:

        age = now.year - birth.year - 1

    if now.month == birth.month and now.day >birth.day:

        age = now.year - birth.year

    person_name = one_person[dct['name']]

    person_id = one_person[dct['id']]

  (2)等级判断:

首先统计慢性病的数目,然后进行等级判断即可

#根据1.2统计慢性病数量

sum_disease = one_person[dct['nb2a']]+one_person[dct['nb2b']]++one_person[dct['nb2c']] \

+ one_person[dct['nb2d']] +one_person[dct['nb2e']] +one_person[dct['nb2f']]  \

+ one_person[dct['nb2g']] + one_person[dct['nb2h']] + one_person[dct['nb2i']] \

+ one_person[dct['nb2j']] +one_person[dct['nb2k']] + int(len(one_person[dct['nb2l']])!=0) \

+ int(len(one_person[dct['nb2m']])!=0)

#1.患病状况:')

t22=''

t22=t22+'您共患有'+str(sum_disease)+'种慢性病\n'

#多重用****

is_multi = one_person[dct['nb3']] == 4

if is_multi:

    #'    您存在多重用****')

    t22 =t22+ '您存在多重用****'+'\n'

#等级判断

my_list=[]

my_list.append(one_person[dct['nb1']])

my_list.append(one_person[dct['nb3']])

my_list.append(one_person[dct['nb4']])

if 4 in my_list:

    #'    您的患病状况维度等级为:较差')

    table.cell(3, 5).text = chr(8730)

    table.cell(3, 5).paragraphs[0].runs[0].font.size = Pt(12)  # 字号大小

    table.cell(3, 5).vertical_alignment = WD_ALIGN_VERTICAL.CENTER  # 垂直居中

    table.cell(3, 5).paragraphs[0].paragraph_format.alignment= WD_ALIGN_PARAGRAPH.CENTER  # 水平居中

elif 3 in my_list:

    #'    您的患病状况维度等级为:中等')

    table.cell(3, 4).text = chr(8730)

    table.cell(3, 4).paragraphs[0].runs[0].font.size = Pt(12)  # 字号大小

    table.cell(3, 4).vertical_alignment = WD_ALIGN_VERTICAL.CENTER  # 垂直居中

    table.cell(3, 4).paragraphs[0].paragraph_format.alignment= WD_ALIGN_PARAGRAPH.CENTER  # 水平居中

else:

    #'    您的患病状况维度等级为:良好')

    table.cell(3, 3).text = chr(8730)

    table.cell(3, 3).paragraphs[0].runs[0].font.size = Pt(12)  # 字号大小

    table.cell(3, 3).vertical_alignment = WD_ALIGN_VERTICAL.CENTER  # 垂直居中

    table.cell(3, 3).paragraphs[0].paragraph_format.alignment= WD_ALIGN_PARAGRAPH.CENTER  # 水平居中

(3)数据计算:

其中需要根据Excel中的数值进行计算,最后根据计算的结果给出评估。代码如下:

a = one_person[dct['ng1a']]

    b = one_person[dct['ng1b']]

    c = one_person[dct['ng2a']]

    d = one_person[dct['ng2b']]

    if a == None:

        a = 12

    if b == None:

        b = 12

    if c == None:

        c = 7.5

    if d == None:

        d = 7.5

    print(one_person[dct['ng1a']])

    body = ((one_person[dct['ng1a']]+one_person[dct['ng1b']])/2) <12 + \

((one_person[dct['ng2a']] +one_person[dct['ng2b']]) / 2)<7.5

    #男 1 女 2

    if one_person[dct['sex']] == 1:

        leg=  ((one_person[dct['ng3a']]+one_person[dct['ng3b']])/2) >= 34

        hand=((one_person[dct['ng4a1']]+one_person[dct['ng4a2']]+one_person[dct['ng4b1']]+one_person[dct['ng4b2']])/4) >=28

    else:

        leg = ((one_person[dct['ng3a']] + one_person[dct['ng3b']]) / 2) >= 33

        hand =((one_person[dct['ng4a1']] +one_person[dct['ng4a2']] +one_person[dct['ng4b1']] + one_person[

            dct['ng4b2']]) / 4) >= 18

    body = body + leg+ hand

    #document.add_paragraph('6.身体测量:')

    t27=''

    if body>=2:

        #document.add_paragraph('    您没有肌衰弱风险')

        t27=t27+'您没有肌衰弱风险'+'\n'

    else:

        #document.add_paragraph('    您具有肌衰弱风险')

        t27 = t27 + '您具有肌衰弱风险' + '\n'

compute_correct = int()

a = one_person[dct['nd4a']]

if a is None :

    a = 0

b = one_person[dct['nd4b']]

if b is None :

    b = 0

c = one_person[dct['nd4c']]

if c is None :

    c = 0

d = one_person[dct['nd4d']]

if d is None :

    d = 0

e = one_person[dct['nd4e']]

if e is None :

    e = 0

compute_correct = (a == 100 - 7) +(b == a - 7) \

                  + (c == b - 7 ) \

                  + (d == c - 7 ) \

                  + (e == d - 7 )

if compute_correct <= 3:

    #document.add_paragraph('    您的注意力和计算力较差')

    t24 = t24 + '您的注意力和计算力较差' + '\n'

spot_correct = one_person[dct['nd5a']] + one_person[dct['nd5b']] +one_person[dct['nd5c']] +one_person[dct['nd5d']] \

               + one_person[dct['nd5e']] + one_person[dct['nd5f']] + one_person[dct['nd5g']]

if spot_correct <= 5:

    #document.add_paragraph('    您的定向力较差')

    t24 = t24 + '您的定向力较差' + '\n'

(4)表格特殊字符和格式处理:

其中包括用程序在表格中打勾和行列宽的设定。代码如下:

table = document.add_table(rows=9, cols=6, style='Table Grid')

table.alignment = WD_TABLE_ALIGNMENT.CENTER # 设置表格为居中对齐

table.autofit = True

# 列宽

col_width_dic = {0: 3, 1: 5, 2: 6, 3: 1, 4: 1, 5: 1}

for col_num in range(6):

    table.cell(0, col_num).width = Inches(col_width_dic[col_num])

# 行高

table.rows[0].height = Cm(0.8)

table.rows[1].height = Cm(1.5)

#打勾

table.cell(4, 3).text = chr(8730)

table.cell(4, 3).paragraphs[0].runs[0].font.size = Pt(12)  # 字号大小

table.cell(4, 3).vertical_alignment = WD_ALIGN_VERTICAL.CENTER  # 垂直居中

table.cell(4, 3).paragraphs[0].paragraph_format.alignment= WD_ALIGN_PARAGRAPH.CENTER  # 水平居中

table.cell(2, 2).text = ''

table.cell(2, 2).paragraphs[0].runs[0].font.size = Pt(12)  # 字号大小

table.cell(2, 2).vertical_alignment = WD_ALIGN_VERTICAL.CENTER  # 垂直居中

table.cell(2, 2).paragraphs[0].paragraph_format.alignment= WD_ALIGN_PARAGRAPH.CENTER  # 水平居中

(5)多人信息保存:

对每个人的数据单独保存成一个表单:

for i,row in enumerate(rows):

    #一个人的资料

    one_person =[col.value for col in row]

document.save('./result/'+str(person_id)+person_name+'.docx')      

最终一键生成了所有人的Word表单,如下图可见:

2.jpg1.jpg

源码地址:

https://pan.baidu.com/s/1YHMPEw9rnWqwxAxgPGTpFw

提取码:l9gh

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客