当前位置:首页>python>质效精研 P36 | Python 赋能:质管人也要学一点代码,批量处理病历数据

质效精研 P36 | Python 赋能:质管人也要学一点代码,批量处理病历数据

  • 2026-08-19 19:00:00
质效精研 P36 | Python 赋能:质管人也要学一点代码,批量处理病历数据
📄核心摘要

项目编号:质效精研 · P36专业领域:医疗质量管理 / 数据分析 / 质管信息化核心问题:质管办每天面对海量 Excel、CSV、数据库导出文件,手工核查 1 个月的病案首页要 3 天,一个 Python 脚本只要 10 分钟——质管人要不要学代码?三条战线:

  • 🟢 基础扫盲:Python 在医院质管的现实价值、3 个 80% 问题、Excel → SQL → Python 学习路径、5 大应用清单
  • 🟡 实战进阶:5 个核心库 + 10 个质控实战场景(全部带 Python 代码)+ 质控 Checklist
  • 🔴 极客升维:Jupyter Notebook 协作、Jinja2 自动报表、病历文本 NLP、Streamlit 简易 Web 应用目标篇幅:9,000-11,000 字

前言:周三下午 4 点,质控员小李的 3 天 vs Python 的 10 分钟

周三下午 4 点,深圳市某三甲医院质管办。

质控员小李对着电脑发呆。桌面上摊着 30 个 Excel——HIS 系统导出的「2026 年 5 月全院病案首页数据」,每个科室 1 个文件,共 12,847 条记录。她需要做的事很明确:

  • 核查主要诊断编码是否为空;
  • 核查主要手术操作是否漏填;
  • 核查入院病情与出院诊断是否符合;
  • 核查 24 小时内归档率;
  • 统计每个科室的入组率、CMI、时间消耗指数;
  • 输出 1 份 30 页的《5 月病案首页质控月报》。

按她过去 3 年的经验,这事要 3 天——一个字段一个字段筛选、复制、粘贴、汇总,中间还要反复核对。

她叹了口气,打开一个新的 Jupyter Notebook,在第一个单元格里敲下:

1
2
3
4
import pandas as pddf = pd.concat([pd.read_excel(f) for f in files], ignore_index=True)print(df.shape)  # (12847, 86)

10 分钟后,她把月报交给主任。主任看了 3 秒,问了一句:“你今天怎么这么快?”

她说:"我学了一点 Python。"

这就是 P36 要讲的事——质管人要不要学代码?答案是:要。但不是「成为程序员」,而是「让代码替我干重复活」

这一篇,我们讲清楚四件事:

  1. Python 在医院质管的现实价值,以及「3 个 80%」问题;
  2. 5 个核心库 + 10 个实战场景(每个场景都带可运行的 Python 代码);
  3. 极客层面的协作、自动报表、NLP、Web 应用;
  4. 一位三甲医院质控员的真实转型案例,以及 30 天行动清单。

不绕弯子,我们开始。

Part 1:基础扫盲层——质管人要不要学 Python?

很多质管同行听到「Python」「代码」,第一反应是「那是信息科的事」「我是医生不是程序员」「学了也用不上」。

这三种反应都对——但都不完整。

一、Python 在医院质管的现实价值

先看 4 个真实场景,看完你再决定要不要学:

场景 1:批量核查病案首页

人工核查 1 个月病案首页 12,847 条 → 3 天; Python 脚本 10 分钟,准确率 100%(代码不会累)。

场景 2:月度指标趋势图自动生成

人工做 1 张折线图 → 30 分钟(HIS 导出 → Excel 整理 → 选数据 → 调格式); Python 一行代码 → 2 秒:df.plot.line()

场景 3:DRG 入组结果核查

人工对照 1 个 DRG 分组器的输出 → 半天; Python 脚本批量对照 → 3 分钟。

场景 4:抗菌药物 DDDs(Defined Daily Doses,限定日剂量)计算

人工查 WHO ATC 编码 → 对照 DDD 值 → 求和 → 半天; Python 用 pandas + merge → 5 分钟。

这就是 Python 在医院质管的现实价值——它不是「替代人」,而是「把人从重复劳动里解放出来」

一个公式总结:

质管人的时间分配 = 80% 重复劳动 + 20% 真正的「分析 + 决策」Python 的作用 = 把那 80% 重复劳动压缩到 5%

二、质管人学 Python 的「3 个 80%」问题

我把它总结成「3 个 80%」——这是质管人学 Python 的「必要性证明」:

80% 的工作是重复的

质管办的日常工作里,至少有 80% 是「周期性重复」的:每月 1 次的病案首页核查、每月 1 次的指标月报、每季度 1 次的三级公立医院绩效考核数据填报、每次医保飞检前的数据准备、每次三级评审条款的自评表。

这些工作「流程固定、数据格式固定、输出格式固定」——正是 Python 最擅长干的活

80% 的数据格式是规整的

医院的数据看似杂乱,其实 80% 都是规整的结构化数据:HIS 导出的 Excel(每个字段都有固定列名)、病案首页(国家卫健委统一规范的 86 项字段)、DRG 分组器输出(标准 CSV)、不良事件上报系统(标准字段)、临床路径系统(标准字典)。

规整的数据 = Python 的菜。Python 最怕的是「非结构化」,比如一份手写病程记录扫描件——但这种数据只占质管工作的 20%。

80% 的分析只用到 20% 的语法

Python 有 30+ 关键字、上百个内置函数、上万个第三方库——但质管人 80% 的日常分析,只用 5 个库 + 20% 的语法:

用途
质管场景使用频率
pandas
表格处理
每天
openpyxl
Excel 读写
每天
pymysql
 / sqlalchemy
数据库连接
每周
matplotlib
 / seaborn
图表
每周
numpy
数值计算
每周

也就是说,质管人不需要「精通 Python」,只需要「会用这 5 个库的 20% 功能」

ℹ️老炮提醒

质管人学 Python,不是「转行当程序员」,而是「给质管工作装一个外挂」。你不需要懂 Python 的内存管理、多线程、装饰器——你只需要懂「怎么让 Python 替我读 Excel、出报表、画图」。

三、学习路径:Excel → SQL → Python(阶梯式)

很多质管同行一上来就买《Python 编程:从入门到实践》,啃了 200 页,放弃了——因为书里讲的是「开发一个网站」「写一个小游戏」,跟医院质管完全脱节。

我推荐一条「阶梯式」学习路径,每一步都跟质管工作直接挂钩:

第 1 阶:Excel 高手(0-3 个月)

如果你 Excel 还在用「筛选 + 复制粘贴」的阶段,先别碰 Python。先把 Excel 学到「数据透视表 + VLOOKUP + 简单函数」的阶段——这一步解决 50% 的日常工作。

第 2 阶:SQL 入门(3-6 个月)

SQL 是「结构化查询语言」,专门用来「问数据库要数据」。医院 HIS、LIS、EMR(电子病历,Electronic Medical Record)系统背后基本都是 MySQL 或 Oracle 数据库——学会 SQL,你就能「直接问数据库要数据」,不用等信息科导出 Excel。

第 3 阶:Python 入门(6-12 个月)

SQL 学到「能自己取数」之后,再学 Python。Python 的入门只需 3 个核心概念:变量与数据类型(数字、字符串、列表、字典)、流程控制(if / for / while)、函数与库(def / import)。把这 3 个概念学会,就能开始写「自动化脚本」了。

第 4 阶:pandas 实战(12-18 个月)

学会 Python 基础语法后,主攻 pandas——这是质管人 80% 工作会用的库。学完 pandas,你的 Excel 工作量会减少 70%。

第 5 阶:可视化 + 数据库 + 报表自动化(18-24 个月)

最后是 matplotlib / seaborn(画图)、pymysql(读数据库)、Jinja2(自动报表)——这是「极客层」的进阶。

💡给质管人的学习节奏建议
  • 不要一次性学完所有语法——用啥学啥,边用边学;
  • 每学一个语法,立刻找一个质管场景练手;
  • 3 个月不写代码,就忘了——保持每周写 1-2 次。

四、质控场景的 Python 应用清单

为了让你对「Python 在医院质管能干啥」有直观印象,我列一份应用清单(后续章节会逐个展开):

应用方向
典型场景
替代的人工工作量
数据清洗
去重、缺失值处理、异常值识别
1 周 → 10 分钟
统计计算
CMI、时间消耗指数、DDDs、入组率
1 天 → 5 分钟
报表自动化
月报、季报、年报、专项报告
1 周 → 1 小时
可视化
趋势图、分布图、对比图、驾驶舱
1 天 → 30 分钟
数据质量核查
病案首页核查、字段完整性、逻辑校验
3 天 → 10 分钟
文本分析
病程记录关键词提取、不良事件分类
1 周 → 30 分钟
数据库直连
直接从 HIS 取数,不用等信息科导出
每次节省 1-2 天
Web 应用
质控员在线核查工具、科室自助查询
自建轻量工具

到这里,你应该明白了:Python 不是「程序员的专利」,而是「质管人的外挂」。下一步,我们进入「怎么用」——5 个核心库 + 10 个实战场景。

Part 2:实战进阶层——5 个核心库 + 10 个质控场景

这一节,我们把质管人最常用的 5 个 Python 库 + 10 个实战场景,逐个拆给你看。每个场景都配可运行的代码——你复制粘贴就能用。

一、5 个核心库速览

在写代码之前,先把 5 个核心库「装到你的工具箱」里:

1. pandas:表格数据处理(最重要)

pandas 的核心数据结构是 DataFrame(可以理解为「加强版 Excel 表」)。一行代码读 Excel:

1
2
3
4
5
6
7
8
import pandas as pddf = pd.read_excel('5月病案首页.xlsx')print(df.head())      # 看前 5 行print(df.shape)       # (12847, 86)  12847 行,86 列print(df.columns)     # 所有列名print(df.dtypes)      # 每列的数据类型print(df.describe())  # 数值列的统计描述

2. numpy:数值计算

numpy 是 pandas 的「底层引擎」,处理矩阵和数值运算:

1
2
3
4
5
import numpy as nparr = np.array([1, 2, 3, 4, 5])print(arr.mean())  # 3.0print(arr.std())   # 1.4142135623730951

3. matplotlib / seaborn:可视化

matplotlib 是 Python 最基础的绘图库,seaborn 是「美化版」:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import matplotlib.pyplot as plt# 折线图:某指标 12 个月趋势months = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']values = [85, 87, 86, 88, 90, 89, 91, 92, 93, 92, 94, 95]plt.rcParams['font.sans-serif'] = ['SimHei']plt.rcParams['axes.unicode_minus'] = Falseplt.figure(figsize=(10, 5))plt.plot(months, values, marker='o')plt.title('CMI 月度趋势')plt.xlabel('月份')plt.ylabel('CMI')plt.grid(True)plt.savefig('cmi_trend.png', dpi=200)plt.show()

4. openpyxl:Excel 读写

openpyxl 主要用来「精细控制 Excel 样式」(合并单元格、设置字体、加颜色):

1
2
3
4
5
6
7
8
9
10
11
12
13
from openpyxl import load_workbookfrom openpyxl.styles import Font, PatternFillwb = load_workbook('月报.xlsx')ws = wb.active# 设置标题字体ws['A1'].font = Font(bold=True, size=14)# 设置单元格颜色ws['A1'].fill = PatternFill(start_color='FFFF00', end_color='FFFF00', fill_type='solid')wb.save('月报_样式.xlsx')

5. pymysql / sqlalchemy:数据库连接

pymysql 直连 MySQL,sqlalchemy 是「ORM 版」更通用:

1
2
3
4
5
6
7
8
9
10
11
12
import pymysqlconn = pymysql.connect(    host='10.1.2.3',         # HIS 数据库地址    user='quality_reader',   # 只读账号    password='******',    database='his_db',    charset='utf8mb4')df = pd.read_sql('SELECT * FROM diagnosis LIMIT 1000', conn)conn.close()
⚠️数据库访问安全提示
  • 不要用 root / admin 账号直连生产库——申请只读账号;
  • 不要在脚本里写明文密码——用环境变量或密钥管理;
  • 不要在脚本里改数据——分析脚本只读,不改。

二、10 个实战场景(全部带代码)

下面 10 个场景覆盖质管办 80% 的日常工作。每个场景包含「场景描述 + 完整代码 + 运行说明」。

场景 1:批量读取 HIS 导出的 Excel

场景:HIS 系统每月导出 30 个科室的病案首页 Excel,每个文件结构相同。需要合并成 1 个总表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import pandas as pdimport globimport os# 1. 找到所有 Excel 文件files = glob.glob('data/病案首页_2026年5月_*.xlsx')print(f'共找到 {len(files)} 个文件')# 2. 循环读取并合并dfs = []for f in files:    dept_name = os.path.basename(f).replace('病案首页_2026年5月_', '').replace('.xlsx', '')    df = pd.read_excel(f)    df['科室'] = dept_name  # 加 1 列「科室」,方便后续分组    dfs.append(df)# 3. 合并所有 DataFramedf_all = pd.concat(dfs, ignore_index=True)print(f'合并后总行数:{len(df_all)}')# 4. 保存df_all.to_excel('output/5月病案首页_全院合并.xlsx', index=False)

效率:30 个文件,合并时间 5-10 秒;手工复制粘贴至少 2 小时。

场景 2:数据清洗(去重 / 缺失值 / 异常值)

场景:合并后的全院数据有重复行、有缺失值、有异常值,需要清洗。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import pandas as pddf = pd.read_excel('output/5月病案首页_全院合并.xlsx')# 步骤 1:去重print(f'去重前行数:{len(df)}')df = df.drop_duplicates(subset=['住院号'], keep='first')print(f'去重后行数:{len(df)}')# 步骤 2:缺失值处理missing_rate = df.isnull().sum() / len(df) * 100print('缺失率 > 5% 的列:')print(missing_rate[missing_rate > 5].sort_values(ascending=False))df = df.dropna(subset=['主要诊断编码'])median_age = df['年龄'].median()df['年龄'] = df['年龄'].fillna(median_age)df['婚姻状况'] = df['婚姻状况'].fillna('未知')# 步骤 3:异常值处理abnormal_age = df[(df['年龄'] < 0) | (df['年龄'] > 150)]print(f'年龄异常记录:{len(abnormal_age)} 条')df = df[(df['年龄'] >= 0) & (df['年龄'] <= 150)]df = df[(df['住院天数'] >= 0) & (df['住院天数'] <= 365)]df = df[df['性别'].isin(['男', '女', '未知'])]print(f'清洗后行数:{len(df)}')

效果:清洗后数据「干净度」从 80% 提升到 99%。

场景 3:数据合并(多表 JOIN)

场景:有两张表——「患者信息表」(patient_id, 姓名, 性别, 年龄)、「诊断记录表」(patient_id, 诊断编码, 诊断名称)。需要合并成 1 张表用于分析。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import pandas as pddf_patient = pd.read_excel('data/患者信息.xlsx')df_diagnosis = pd.read_excel('data/诊断记录.xlsx')# 内连接(只保留有诊断的患者)df_merged = pd.merge(df_patient, df_diagnosis, on='patient_id', how='inner')# 左连接(保留所有患者,没诊断的填 NaN)df_left = pd.merge(df_patient, df_diagnosis, on='patient_id', how='left')print(f'患者表行数:{len(df_patient)}')print(f'诊断表行数:{len(df_diagnosis)}')print(f'内连接后:{len(df_merged)}')

SQL 对照:SELECT * FROM patient p INNER JOIN diagnosis d ON p.patient_id = d.patient_id;

场景 4:病案首页关键字段核查

场景:病案首页 86 项字段中,有 15 项是「必填且非空」的。需要自动核查,生成问题清单。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import pandas as pddf = pd.read_excel('output/5月病案首页_全院合并.xlsx')required_fields = [    '住院号', '姓名', '性别', '年龄', '入院日期', '出院日期',    '主要诊断编码', '主要诊断名称',    '主要手术操作编码', '主要手术操作名称',    '入院病情', '出院病情', '科别', '床位医师']issues = []for field in required_fields:    if field not in df.columns:        print(f'警告:字段「{field}」不存在')        continue    missing_count = df[field].isnull().sum()    empty_count = (df[field].astype(str).str.strip() == '').sum()    total_problems = missing_count + empty_count    issues.append({        '字段': field,        '缺失数': missing_count,        '空白数': empty_count,        '总问题数': total_problems,        '问题率(%)': round(total_problems / len(df) * 100, 2)    })df_issues = pd.DataFrame(issues).sort_values('总问题数', ascending=False)print(df_issues)df_issues.to_excel('output/病案首页必填字段核查报告.xlsx', index=False)

输出:

1
2
3
4
       字段   缺失数   空白数   总问题数  问题率(%)   主要手术操作名称   1245    89    1334    10.38   主要手术操作编码   1203    89    1292    10.06   入院病情         56      0     56      0.44

场景 5:不良事件分类统计

场景:护理部上报的不良事件数据,需要按「级别 + 类别 + 科室」三维统计。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import pandas as pddf = pd.read_excel('data/2026年不良事件.xlsx')# 透视表:按级别 × 类别pivot1 = df.pivot_table(    index='事件级别', columns='事件类别', values='事件ID',    aggfunc='count', fill_value=0, margins=True, margins_name='合计')print('事件级别 × 事件类别:')print(pivot1)# 按科室统计,降序dept_stats = df.groupby('科室').agg(    事件总数=('事件ID', 'count'),    严重事件数=('事件级别', lambda x: (x == '严重').sum()),    已结案数=('状态', lambda x: (x == '已结案').sum())).sort_values('事件总数', ascending=False)print('科室统计:')print(dept_stats)with pd.ExcelWriter('output/不良事件统计月报.xlsx', engine='openpyxl') as writer:    pivot1.to_excel(writer, sheet_name='级别×类别')    dept_stats.to_excel(writer, sheet_name='科室统计')

场景 6:抗菌药物 DDDs 自动计算

场景:药剂科要求每月统计抗菌药物 DDDs(DDDs = 总用药量 / DDD 值),衡量抗菌药物使用强度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import pandas as pddf_use = pd.read_excel('data/5月抗菌药物使用记录.xlsx')df_ddd = pd.read_excel('data/抗菌药物DDD字典.xlsx')df_merged = pd.merge(df_use, df_ddd, on='药物编码', how='left')df_merged['DDDs'] = df_merged['用药总量(克)'] / df_merged['DDD值(克)']drug_ddds = df_merged.groupby(['药物名称', 'ATC分类']).agg(    用药总量=('用药总量(克)', 'sum'),    DDDs=('DDDs', 'sum')).sort_values('DDDs', ascending=False)print(drug_ddds.head(20))df_dept = df_merged.groupby('科室').agg(    DDDs合计=('DDDs', 'sum'),    住院人天=('住院人天', 'sum'))df_dept['DDDs_100人天'] = df_dept['DDDs合计'] / df_dept['住院人天'] * 100print('科室抗菌药物使用强度:')print(df_dept.sort_values('DDDs_100人天', ascending=False))
ℹ️关于 DDDs

DDDs(DDDs,Defined Daily Doses,限定日剂量数)反映的是「每种药物被使用的平均日剂量数」,数值越大,说明该药使用越广泛。WHO ATC/DDD 系统是国际通用的药物计量标准。

场景 7:临床路径入径率分析

场景:统计每个科室每个月的「临床路径入径率」「完成率」「变异率」。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import pandas as pddf = pd.read_excel('data/临床路径数据_2026.xlsx')grouped = df.groupby(['科室', '月份', '路径名称']).agg(    符合路径=('是否符合', lambda x: (x == '是').sum()),    实际入径=('是否入径', lambda x: (x == '是').sum()),    完成路径=('是否完成', lambda x: (x == '是').sum()),    发生变异=('是否变异', lambda x: (x == '是').sum()))grouped['入径率'] = grouped['实际入径'] / grouped['符合路径'] * 100grouped['完成率'] = grouped['完成路径'] / grouped['实际入径'] * 100grouped['变异率'] = grouped['发生变异'] / grouped['实际入径'] * 100grouped = grouped.round(2)high_variation = grouped[grouped['变异率'] > 30].sort_values('变异率', ascending=False)print('高变异率路径:')print(high_variation)grouped.to_excel('output/临床路径入径率分析.xlsx')

场景 8:DRG 入组结果核查

场景:DRG 分组器输出的入组结果,需要核查「入组率」「低风险死亡率」「错误入组」。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import pandas as pddf = pd.read_excel('data/5月DRG入组结果.xlsx')# 总体入组率total_rate = (df['DRG编码'].notnull().sum() / len(df)) * 100print(f'全院 DRG 入组率:{total_rate:.2f}%')# 各科室入组率dept_rate = df.groupby('科室').apply(    lambda x: pd.Series({        '病例数': len(x),        '入组数': x['DRG编码'].notnull().sum(),        '入组率(%)': round(x['DRG编码'].notnull().sum() / len(x) * 100, 2)    })).sort_values('入组率(%)', ascending=False)warning = dept_rate[dept_rate['入组率(%)'] < 95]print('入组率 < 95% 的科室:')print(warning)# CMI 计算total_weight = df['DRG权重'].sum()cni_count = len(df[df['DRG编码'].notnull()])cmi = total_weight / cni_countprint(f'全院 CMI:{cmi:.4f}')dept_rate.to_excel('output/DRG入组率核查.xlsx')

场景 9:指标月度趋势图自动生成

场景:每月输出 5-10 个关键指标的「趋势图」,用于月报。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import pandas as pdimport matplotlib.pyplot as pltimport osplt.rcParams['font.sans-serif'] = ['SimHei']plt.rcParams['axes.unicode_minus'] = Falsedf = pd.read_excel('data/2025年指标数据.xlsx')os.makedirs('output/趋势图', exist_ok=True)indicators = ['CMI', '入组率', '平均住院日', '抗菌药物使用强度', '手术并发症发生率']fig, axes = plt.subplots(2, 3, figsize=(15, 10))axes = axes.flatten()for i, ind in enumerate(indicators):    if ind not in df.columns:        continue    ax = axes[i]    ax.plot(df['月份'], df[ind], marker='o', linewidth=2)    ax.set_title(ind, fontsize=14)    ax.set_xlabel('月份')    ax.set_ylabel(ind)    ax.grid(True, alpha=0.3)    ax.tick_params(axis='x', rotation=45)for j in range(len(indicators), len(axes)):    axes[j].set_visible(False)plt.tight_layout()plt.savefig('output/趋势图/月度指标趋势图.png', dpi=200, bbox_inches='tight')plt.show()print('趋势图已生成')

场景 10:数据质量自动报告

场景:每月自动出一份《数据质量报告》,包括「完整性、一致性、及时性、唯一性」四个维度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import pandas as pdfrom datetime import datetimedf = pd.read_excel('output/5月病案首页_全院合并.xlsx')report = []report.append(f'数据质量报告 - {datetime.now().strftime("%Y-%m-%d")}')report.append(f'总记录数:{len(df)}')report.append('=' * 50)# 完整性report.append('\n【维度 1:完整性】')required_fields = ['主要诊断编码', '主要手术操作编码', '入院病情', '出院病情']for field in required_fields:    if field in df.columns:        missing_rate = df[field].isnull().sum() / len(df) * 100        status = '通过' if missing_rate < 1 else '不通过'        report.append(f'  {field}:缺失率 {missing_rate:.2f}% [{status}]')# 一致性report.append('\n【维度 2:一致性】')invalid_date = (df['入院日期'] >= df['出院日期']).sum()report.append(f'  入院日期 >= 出院日期:{invalid_date} 条')icd_pattern = df['主要诊断编码'].astype(str).str.match(r'^[A-Z]\d{2}(\.\d{1,2})?$')invalid_icd = (~icd_pattern & df['主要诊断编码'].notnull()).sum()report.append(f'  主要诊断编码格式不规范:{invalid_icd} 条')# 及时性report.append('\n【维度 3:及时性】')df['归档时效'] = (df['归档日期'] - df['出院日期']).dt.total_seconds() / 3600on_time_rate = (df['归档时效'] <= 24).sum() / len(df) * 100report.append(f'  24 小时内归档率:{on_time_rate:.2f}%')# 唯一性report.append('\n【维度 4:唯一性】')duplicate_id = df.duplicated(subset=['住院号'], keep=False).sum()report.append(f'  住院号重复:{duplicate_id} 条')with open('output/数据质量报告_5月.txt', 'w', encoding='utf-8') as f:    f.write('\n'.join(report))print('\n'.join(report))

输出示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
数据质量报告 - 2026-06-24总记录数:12847==================================================【维度 1:完整性】  主要诊断编码:缺失率 0.12% [通过]  主要手术操作编码:缺失率 10.06% [不通过]【维度 2:一致性】  入院日期 >= 出院日期:3 条  主要诊断编码格式不规范:127 条【维度 3:及时性】  24 小时内归档率:89.32%【维度 4:唯一性】  住院号重复:0 条

三、质控 Checklist:10 项核查点

Python 脚本写完后,怎么知道脚本「靠不靠谱」?用这张 Checklist:

序号
核查项
检查方法
通过标准
1
脚本运行成功率
连续 3 个月运行同一脚本
≥ 99%
2
数据准确率
与人工核查 100 条样本对比
≥ 99%
3
效率提升比
对比脚本运行时长 vs 人工时长
≥ 10 倍
4
字段口径一致性
与指标库定义文档比对
100% 一致
5
空值 / 异常值处理
故意构造 100 条异常数据测试
全部按预期处理
6
版本控制
脚本用 git 管理,变更可追溯
所有变更在 git log
7
文档完整性
每个脚本有 README,说明输入 / 输出 / 依赖
100% 覆盖
8
权限最小化
数据库账号只有读权限
验证账号权限
9
可重复运行
同一脚本运行两次结果一致
完全一致
10
维护成本
每季度人工维护时长
≤ 4 小时/季度
💡落地建议

把这张 Checklist 嵌入 CI/CD(持续集成/持续部署)流水线,每次脚本变更前自动跑一遍——脚本质量有保障,才不会「跑 1 次准,跑 100 次偏」。

到这里,10 个实战场景 + 5 个核心库都拆完了。但这只是「会用 Python」的阶段——下一步,我们看「把 Python 用到极致」的极客层面。

Part 3:极客升维层——从「脚本」到「系统」

上一节的脚本,适合个人使用;这一节的工具,适合团队协作 + 流程自动化。

一、Jupyter Notebook:质管团队的协作神器

Jupyter Notebook 是一种「交互式编程环境」——你可以一段一段地写代码,每一段的结果(表格、图表、文字)直接显示在代码下面。

为什么质管团队特别适合用 Jupyter?

传统脚本
Jupyter Notebook
一次跑完,中间看不到结果
一段段执行,每段有输出
文字说明要写在另一个文档
文字 + 代码 + 图表混排
团队协作靠 git diff
直接看「输出」就知道改了什么
出问题要从头跑
可以只跑出问题的部分

质管团队用 Jupyter 的 3 个真实场景:

  1. 月报协作: 质管办 3 个人分工写 3 个 Cell,合并成 1 个月报 Notebook;
  2. 培训教学: 信息科给临床讲解数据时,用 Jupyter 边讲边演示;
  3. 复盘分析: 事故复盘时,用 Jupyter 一步步追溯数据,留作「事故档案」。

二、Python 自动化报表(Jinja2 + PDF)

场景:每月要出 1 份《全院质控月报》(PDF),内容固定,只是数据变。

方案:用 Jinja2(模板引擎)+ WeasyPrint(PDF 生成器)——把「文字模板 + 数据」自动合并成 PDF。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
from jinja2 import Templateimport pandas as pdfrom datetime import datetimedf = pd.read_excel('output/5月病案首页_全院合并.xlsx')total = len(df)grouped_rate = df['DRG编码'].notnull().sum() / total * 100cmi = df['DRG权重'].sum() / df['DRG编码'].notnull().sum()data = {    'report_month': '2026年5月',    'generate_date': datetime.now().strftime('%Y-%m-%d'),    'total_cases': total,    'drg_rate': f'{grouped_rate:.2f}',    'cmi': f'{cmi:.4f}',    'avg_los': f'{df["住院天数"].mean():.2f}'}template_str = """<!DOCTYPE html><html><head><meta charset="utf-8"><title>质控月报</title></head><body><h1>{{ report_month }} 全院质控月报</h1><p>生成日期:{{ generate_date }}</p><h2>一、总体情况</h2><ul>  <li>出院病例总数:<b>{{ total_cases }}</b> 例</li>  <li>DRG 入组率:<b>{{ drg_rate }}%</b></li>  <li>CMI:<b>{{ cmi }}</b></li>  <li>平均住院日:<b>{{ avg_los }}</b> 天</li></ul></body></html>"""template = Template(template_str)html_content = template.render(**data)with open('output/月报.html', 'w', encoding='utf-8') as f:    f.write(html_content)# 转 PDF(需要安装 weasyprint)# from weasyprint import HTML# HTML(string=html_content).write_pdf('output/月报.pdf')

效果:改模板,数据自动填入;每月只需跑 1 次脚本,PDF 月报自动生成。

三、病历文本 NLP(关键词提取)

场景:病程记录、出院小结是「非结构化文本」,如何自动提取关键信息?

方案:用 jieba(中文分词)+ re(正则表达式)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import jiebaimport resample_text = """患者于 2026-05-10 在全身麻醉下行腹腔镜下胆囊切除术,术中出血约 50ml,术后安返病房。术后第 2 天出现发热,体温最高 38.5℃,考虑切口感染,给予头孢呋辛钠抗感染治疗后好转。"""# 中文分词words = jieba.lcut(sample_text)print('分词结果:')print('/'.join(words))# 提取关键信息surgery_match = re.search(r'行(.*?术)[,。]', sample_text)if surgery_match:    print(f'手术名称:{surgery_match.group(1)}')dates = re.findall(r'\d{4}-\d{2}-\d{2}', sample_text)print(f'涉及日期:{dates}')temps = re.findall(r'(\d+\.?\d*)℃', sample_text)print(f'体温记录:{temps}')complication_keywords = ['感染', '出血', '发热', '疼痛', '肿胀', '渗出']found = [k for k in complication_keywords if k in sample_text]print(f'并发症关键词:{found}')

输出:

1
2
3
4
手术名称:腹腔镜下胆囊切除术涉及日期:['2026-05-10']体温记录:['38.5']并发症关键词:['感染', '发热']

进阶:用 sklearn 的 TF-IDF 或 BERT 模型做「病历自动分类」(病种、病情严重程度)——这一层需要更多 NLP 基础,可以放到 P37 详述。

四、Streamlit:5 分钟做一个 Web 应用

场景:质管办做了一个「病案首页核查工具」脚本,但临床科室不会用 Python——怎么让临床也能用?

方案:用 Streamlit 把 Python 脚本包装成 Web 应用,临床打开浏览器就能用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# streamlit_app.pyimport streamlit as stimport pandas as pdst.title('病案首页核查工具')uploaded = st.file_uploader('上传病案首页 Excel', type=['xlsx'])if uploaded:    df = pd.read_excel(uploaded)    st.success(f'共读取 {len(df)} 条记录')    st.subheader('必填字段核查')    required = ['主要诊断编码', '主要手术操作编码', '入院病情']    for field in required:        if field in df.columns:            missing = df[field].isnull().sum()            rate = missing / len(df) * 100            if rate > 5:                st.error(f'{field}:缺失 {missing} 条 ({rate:.2f}%) - 不通过')            else:                st.success(f'{field}:缺失 {missing} 条 ({rate:.2f}%) - 通过')    if st.checkbox('显示原始数据'):        st.dataframe(df.head(100))

运行:streamlit run streamlit_app.py,打开浏览器访问 http://localhost:8501,临床就能直接上传 Excel 看核查结果——完全不用懂 Python

五、整体架构(Mermaid 图)

为了让你看清「Python 自动化体系」的全貌,画一张架构图:

六、工作流流程图(Mermaid)

再画一张「质控员日常 Python 工作流」:

到这里,极客层面的工具都摆齐了。但这一切要落地,中间还隔着「人」这道坎——下一节,我们走进一家三甲医院的真实场景,看一个质控员是怎么从「手工」走到「自动化」的。

Part 4:真实案例——某三甲医院质控员的 Python 转型之路

2025 年,深圳某三甲医院(化名「海珠医院」,开放床位 1800 张,日均门诊 9000 人次)质管办来了一位新人——小陈,护理学硕士,刚毕业 1 年。

一、起点:3 天 vs 10 分钟

小陈入职第 1 周:

  • 主任交代:「把 2025 年 1 月的病案首页核查报告做出来」;
  • 数据:1 个 Excel,8,234 条;
  • 工作内容:核查 15 个必填字段、统计 30 个科室的入组率、生成 1 份月报;
  • 用时:3 天(筛选、复制、粘贴、汇总、出图表、写报告)。

小陈入职第 3 个月:

  • 同样的工作,她用 Python 脚本完成;
  • 用时:10 分钟(脚本 1 次运行,自动出报表、自动出图、自动生成月报)。

效率提升:432 倍

二、转型路径:6 个月从「零基础」到「自动化」

月份
学习内容
实际产出
第 1 月
Excel 高阶功能 + SQL 基础
把 HIS 导出的 Excel 用 SQL 直连数据库,节省每天 2 小时「等导出」
第 2 月
Python 基础语法 + pandas 入门
写出第 1 个脚本:批量核查必填字段
第 3 月
pandas 进阶 + matplotlib 绘图
月报图表自动化,从「手工画图」变「脚本出图」
第 4 月
openpyxl + Jinja2 报表模板
月报自动生成,从「手工排版」变「模板填充」
第 5 月
pymysql + 数据库直连
直连 HIS 数据库,不用等信息科导出
第 6 月
Streamlit + 团队协作
给临床做了一个「病案首页在线核查」Web 工具

三、改革效果(6 个月后)

维度
改革前
改革后
变化
月报出稿时间
3 天
1 小时
-92%
数据准确率
95%(手工有错)
99.5%(代码不累)
+4.5 pp
临床「等数据」时长
每周 4 小时
每周 0.5 小时
-87.5%
质管办可分析维度
5-8 个
20+ 个
+150%

四、三条经验

📋小陈的转型经验
  1. 从「最痛的一个点」切入: 小陈第 1 个脚本不是「全院自动化」,而是「必填字段核查」——就这一件事,让她每天节省 1 小时,从此有了「继续学」的动力。
  2. 每学一个语法,立刻找一个质管场景练手: 她学 merge 的那天,就找了「患者表 + 诊断表合并」这个真实场景;学 groupby 的那天,就找了「按科室统计入组率」。学以致用,3 个月就出师
  3. 把自己变成「团队的桥梁」: 小陈学会 Python 后,主动帮信息科写脚本、帮临床做核查工具——她从「新人」变成了「质管办最被需要的人」。技能,是医院里最硬的「关系」

到这里,4 个层级都拆完了。最后,我们给出 30 天行动清单 + P37 预告。

结语:Python 不是「程序员的专利」,是「质管人的外挂」

回到周三下午 4 点的小李。

她面前的那 30 个 Excel 不会消失——病案首页每个月都要核查,月报每个月都要出,指标每个月都要统计。但从今天起,她做三件事:

第一,装上 Python 环境——Anaconda 一键安装,30 分钟搞定。

第二,写第 1 个脚本——哪怕只是「读 1 个 Excel,看前 5 行」——只要迈出第一步,后面就顺了。

第三,加入 1 个 Python 质管社群——遇到问题有人问、有人答,比自己摸索快 10 倍。

她不需要成为程序员,她只需要让 Python 替她干那 80% 的重复活

全文三句话

一句话总结
  1. 质管人学 Python 不是「转行」,是「给质管工作装外挂」——3 个 80% 问题决定了学 Python 是「性价比最高的技能投资」
  2. 5 个核心库 + 10 个实战场景覆盖质管办 80% 的工作——pandas 读表、numpy 算数值、matplotlib 出图、openpyxl 控 Excel、pymysql 连数据库,这 5 个就够用
  3. 从「脚本」到「系统」要走 3 步:Jupyter Notebook 协作、Jinja2 + PDF 自动报表、Streamlit 做 Web 工具——每一步都让 Python 从「个人技能」升级为「团队能力」

30 天行动清单:从「零基础」到「会写脚本」

💡给质管人的「30 天 Python 入门清单」

| 天数 | 动作 | 输出物 | |—|—|—| | Day 1 | 安装 Anaconda,打开 Jupyter Notebook | 环境就绪 | | Day 2 | 第 1 个脚本:读 1 个 Excel,看前 5 行 | df.head() 运行成功 | | Day 3 | 学 pandas 的 describe() / info() / shape | 3 行代码搞定 | | Day 4 | 学 dropna() / drop_duplicates() | 清洗 1 个真实 Excel | | Day 5 | 学 groupby() + agg() | 按科室统计 1 个指标 | | Day 6 | 实战 1:批量合并 30 个科室的病案首页 | 合并后的总表 | | Day 7 | 实战 2:数据清洗(去重 + 缺失值 + 异常值) | 清洗后的总表 | | Day 8 | 实战 3:病案首页必填字段核查 | 核查报告 Excel | | Day 9 | 学 matplotlib 的 plot() + figure() | 1 张折线图 | | Day 10 | 实战 4:指标月度趋势图自动生成 | 5 张趋势图 PNG | | Day 11 | 学 openpyxl 的 Font + PatternFill | 1 份带样式的 Excel | | Day 12 | 学 pivot_table() | 1 张透视表 | | Day 13 | 实战 5:不良事件分类统计 | 透视表 + 科室统计 | | Day 14 | 学 merge() | 合并 2 张表 | | Day 15 | 学 numpy 的 mean() / std() / median() | 3 个统计函数 | | Day 16 | 实战 6:抗菌药物 DDDs 自动计算 | 科室 DDDs 报表 | | Day 17 | 实战 7:临床路径入径率分析 | 路径入径率报表 | | Day 18 | 实战 8:DRG 入组结果核查 | 入组率 + CMI + 时间消耗指数 | | Day 19 | 实战 9:数据质量自动报告 | 4 维度数据质量报告 | | Day 20 | 学 pymysql 直连 MySQL | 1 个 SQL 查询结果 | | Day 21 | 实战 10:从 HIS 数据库直接取数 | 不再等信息科导出 | | Day 22 | 学 Jinja2 模板语法 | 1 个 HTML 模板 | | Day 23 | 实战:用 Jinja2 生成月报 HTML | 1 份自动月报 | | Day 24 | 学 Streamlit 基础 | 1 个简单 Web 应用 | | Day 25 | 实战:把核查脚本包装成 Streamlit | 临床可用的 Web 工具 | | Day 26 | 学 jieba 中文分词 + re 正则 | 病程记录分词结果 | | Day 27 | 实战:病历文本关键词提取 | 手术名 + 并发症关键词 | | Day 28 | 把所有脚本用 git 管理 | GitHub 仓库 | | Day 29 | 写一份《我的 Python 学习笔记》 | 学习笔记 Markdown | | Day 30 | 30 天复盘:出《P36 30 天落地报告》 | 复盘报告 + 下一阶段计划 |

30 天不是空话,是从「不会 Python」到「会写脚本」的硬约束。 Day 1 必须今天完成,Day 30 必须 30 天后能跑出 1 份自动化月报——这就是质管人学 Python 该有的节奏。


ℹ️系列预告
  • P37 AI 辅助质控: 大语言模型 + 病历质控——AI 能不能帮质控员自动核查病案首页、自动识别疑似医疗不良事件?
  • P38 数据治理实战: 从「脏数据」到「干净数据」——医院数据治理的 6 步法
  • P39 质管信息化选型: 选 HIS、选 BI、选 AI——质管办的信息化该怎么「搭」?

关注「质领未来」,每一篇,都让质管人少走一年弯路。 留言区留下你 学 Python 踩过最深的坑(比如装环境装到崩溃、写脚本写到半夜、出错找不到原因、坚持不下去想放弃……),狼叔会在 P37-P39 里挑 3 个高频痛点做深度拆解。


《质效精研》P36 · Python 赋能:质管人也要学一点代码,批量处理病历数据

📖 扩展阅读

医数智联·第 14 期:Python 入门 —— 医院人零基础友好,30 分钟跑通第一个脚本

质效精研 P35 | 极客工具:Excel 不只是表格,用函数实现质控自动化

医数智联·第 15 期:pandas 入门 —— 首页数据的「Excel 终结者」,DataFrame 10 大操作

医数智联·第 16 期:matplotlib 入门 —— 质控图表自动生成,4 类核心图表代码模板

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-08-21 14:35:18 HTTP/2.0 GET : https://f.mffb.com.cn/a/509586.html
  2. 运行时间 : 0.233505s [ 吞吐率:4.28req/s ] 内存消耗:4,928.38kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=8c74c3cf9a958962fb4cffc7b71b6b3d
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.001117s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001635s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000632s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000580s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001347s ]
  6. SELECT * FROM `set` [ RunTime:0.000482s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001570s ]
  8. SELECT * FROM `article` WHERE `id` = 509586 LIMIT 1 [ RunTime:0.006020s ]
  9. UPDATE `article` SET `lasttime` = 1787294118 WHERE `id` = 509586 [ RunTime:0.022669s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.000703s ]
  11. SELECT * FROM `article` WHERE `id` < 509586 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001114s ]
  12. SELECT * FROM `article` WHERE `id` > 509586 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.001640s ]
  13. SELECT * FROM `article` WHERE `id` < 509586 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.043832s ]
  14. SELECT * FROM `article` WHERE `id` < 509586 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.003569s ]
  15. SELECT * FROM `article` WHERE `id` < 509586 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.020962s ]
0.235034s