3个Python脚本搞定抑郁症数据速查手册搭建 3个Python脚本搞定抑郁症数据速查手册搭建 刚学完Python语法,对着空白的编辑器发呆?别急,这是90%新手都会遇到的“代码孤岛”困境。你会写 for 循环,会定义函数,但一让你搭个完整项目,脑子就一片空白。今天不聊虚的,直接上干货。我们要用Python从零搭建一个针对抑郁症筛查数据的自动化速查手册生成器。这不是为了做医疗诊断,而是为了帮助心理工作者、社区医生或HR快速整理患者自评量表(如PHQ-9)的统计分布、风险等级分类和关键指标汇总。很多机构还在用Excel手动统计,效率低且容易出错。我们要把这个过程代码化、自动化,生成一份清晰、可检索的PDF或Markdown格式速查手册。 项目目标与数据清洗 先明确我们要解决什么痛点。心理评估量表的数据通常是CSV或Excel格式,里面混杂着缺失值、异常值和不同编码格式的评分。我们的目标是:输入原始数据,输出结构化的风险分布报表。 这里有个关键细节:数据标准化。不同机构对“轻度抑郁”的分数段定义可能略有差异。我们参考GitHub开源仓库 psychometrics-tools 中的PHQ-9标准切分点,确保算法符合主流临床标准。 第一步是环境准备。你需要Python 3.8+,以及 pandas 和 numpy 这两个核心库。安装很简单: pip install pandas numpy 接下来是数据加载与清洗。假设我们有一个 phq9_raw.csv 文件,包含 id, score, date, notes 四列。 import pandas as pd import numpy as np def load_and_clean_data(file_path): # 1. 读取CSV文件 df = pd.read_csv(file_path) # 2. 处理缺失值:如果score为空,标记为'unknown',后续单独统计 df['score'] = df['score'].fillna(-1) # 3. 过滤无效数据:PHQ-9总分范围是0-27,超出视为异常 df = df[(df['score'] = 0) (df['score'] = 27)] # 4. 根据标准切分风险等级 # 0-4: 无/极轻微, 5-9: 轻度, 10-14: 中度, 15-19: 中重度, 20-27: 重度 def categorize_risk(score): if score = 4: return 'Low' elif score = 9: return 'Mild' elif score = 14: return 'Moderate' elif score = 19: return 'Moderately Severe' else: return 'Severe' df['risk_level'] = df['score'].apply(categorize_risk) return df 这段代码的逻辑非常清晰。fillna(-1) 是个小技巧,先占位再过滤,避免直接删除行导致数据量骤降。categorize_risk 函数是核心,它把连续的分数离散化为五个等级,这是生成速查手册中“风险分布图表”的基础。 目录结构设计 一个可维护的项目,目录结构比代码本身更重要。很多新手喜欢把所有代码塞进一个 main.py,这是大忌。我们采用模块化设计: depression_manual_gen/ ├── data/ │ └── phq9_raw.csv # 原始数据 ├── src/ │ ├── __init__.py │ ├── data_processor.py # 数据清洗与分类逻辑 │ ├── report_generator.py # 报表生成逻辑 │ └── utils.py # 通用工具函数 ├── output/ │ └── generated/ # 最终生成的手册文件 ├── requirements.txt # 依赖库列表 └── main.py # 程序入口 在 src/utils.py 中,我们写一些通用函数,比如日期格式化、文件路径处理: import os from datetime import datetime def ensure_dir_exists(path): 确保目录存在,不存在则创建 if not os.path.exists(path): os.makedirs(path) return path def get_current_date_string(): 获取当前日期字符串,用于文件命名 return datetime.now().strftime(%Y%m%d) 这种结构的好处是,当你要更换数据源(比如从CSV换成SQL数据库)时,只需要修改 data_processor.py,而不用动报表生成逻辑。这就是工程化的意义。 核心代码实现 现在进入最核心的部分:统计分析与报表生成。我们要计算每个风险等级的占比、平均分、以及环比变化(如果有历史数据)。 在 src/report_generator.py 中,我们实现统计逻辑: import pandas as pd def generate_statistics(df): 生成统计摘要 :param df: 清洗后的DataFrame :return: dict 包含各项统计指标 # 1. 计算总人数 total_count = len(df) # 2. 计算各风险等级人数 risk_counts = df['risk_level'].value_counts() # 3. 计算各等级占比 risk_percentages = (risk_counts / total_count) * 100 # 4. 计算总体平均分 avg_score = df['score'].mean() # 5. 计算中位数,排除极端值影响 median_score = df['score'].median() # 构建结果字典 stats = { 'total_count': total_count, 'avg_score': round(avg_score, 2), 'median_score': round(median_score, 2), 'risk_distribution': { 'Low': {'count': int(risk_counts.get('Low', 0)), 'percent': round(risk_percentages.get('Low', 0), 2)}, 'Mild': {'count': int(risk_counts.get('Mild', 0)), 'percent': round(risk_percentages.get('Mild', 0), 2)}, 'Moderate': {'count': int(risk_counts.get('Moderate', 0)), 'percent': round(risk_percentages.get('Moderate', 0), 2)}, 'Moderately Severe': {'count': int(risk_counts.get('Moderately Severe', 0)), 'percent': round(risk_percentages.get('Moderately Severe', 0), 2)}, 'Severe': {'count': int(risk_counts.get('Severe', 0)), 'percent': round(risk_percentages.get('Severe', 0), 2)} } } return stats 注意这里的 round 函数,保留两位小数是报表的惯例,既精确又整洁。risk_distribution 是一个嵌套字典,方便后续直接渲染成Markdown表格。 接下来,我们把统计结果转换成Markdown格式的速查手册。Markdown比PDF更灵活,可以直接在GitHub或Confluence中查看。 def generate_markdown_report(stats, output_path): 生成Markdown格式报表 :param stats: 统计字典 :param output_path: 输出文件路径 # 构建Markdown内容 md_content = f# 抑郁症筛查数据速查手册\n\n md_content += f**生成时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n md_content += f## 总体概览\n\n md_content += f- **样本总量**: {stats['total_count']} 人\n md_content += f- **平均分**: {stats['avg_score']}\n md_content += f- **中位数**: {stats['median_score']}\n\n md_content += f## 风险等级分布\n\n md_content += f| 风险等级 | 人数 | 占比 (%) |\n md_content += f| :--- | :---: | :---: |\n # 遍历风险等级,生成表格行 for level, data in stats['risk_distribution'].items(): md_content += f| {level} | {data['count']} | {data['percent']} |\n md_content += f\n## 建议与注意事项\n\n md_content += f1. 数据仅供统计参考,不能作为临床诊断依据。\n md_content += f2. 'Severe'等级人群建议优先进行专业评估。\n # 写入文件 with open(output_path, 'w', encoding='utf-8') as f: f.write(md_content) print(f报表已生成: {output_path}) 这段代码的关键在于 f-string 的灵活运用。它让动态内容插入变得非常直观。特别是表格生成部分,通过循环拼接字符串,实现了从数据到可视化的直接转换。 运行与测试 万事俱备,只欠东风。在 main.py 中串联所有模块: import os from src.data_processor import load_and_clean_data from src.report_generator import generate_statistics, generate_markdown_report from src.utils import ensure_dir_exists, get_current_date_string def main(): # 1. 配置路径 data_file = 'data/phq9_raw.csv' output_dir = 'output/generated' ensure_dir_exists(output_dir) # 2. 生成带日期的文件名 filename = fdepression_report_{get_current_date_string()}.md output_file = os.path.join(output_dir, filename) # 3. 执行流程 try: # 加载与清洗 print(正在加载与清洗数据...) df = load_and_clean_data(data_file) # 统计 print(正在计算统计数据...) stats = generate_statistics(df) # 生成报表 print(正在生成Markdown报表...) generate_markdown_report(stats, output_file) print(任务完成!) except FileNotFoundError: print(f错误: 找不到数据文件 {data_file}) except Exception as e: print(f发生未知错误: {e}) if __name__ == __main__: main() 运行 python main.py,你应该会在控制台看到进度提示,并在 output/generated 目录下得到一个 .md 文件。用VS Code打开它,你会看到一个排版整洁的表格,清晰展示了各风险等级的人数和占比。 测试环节不能少。你可以手动修改几行数据,比如把某个 score 改成28(超出范围),运行后确认它被正确过滤。或者把 score 设为空值,确认它被标记并排除在平均分计算之外。这种边界测试是保证生产环境稳定性的关键。 优化扩展 基础版本跑通了,但这只是起点。实际工作中,数据量可能达到十万级,或者需要更复杂的分析。这里有几个优化方向: 1. 性能优化 如果数据量极大,pandas 的 apply 函数会变慢。可以尝试向量化操作,或者使用 numpy 的直接索引。对于实时性要求高的场景,可以考虑引入 polars 库,它的速度比 pandas 快一个数量级。 2. 可视化增强 纯文本表格虽然清晰,但不够直观。引入 matplotlib 或 plotly,生成柱状图或饼图,并嵌入Markdown中。例如: import matplotlib.pyplot as plt def plot_risk_distribution(stats): levels = list(stats['risk_distribution'].keys()) counts = [stats['risk_distribution'][level]['count'] for level in levels] plt.figure(figsize=(10, 6)) plt.bar(levels, counts, color=['#2ecc71', '#f1c40f', '#e67e22', '#e74c3c', '#c0392b']) plt.title('Depression Risk Distribution') plt.ylabel('Count') plt.tight_layout() plt.savefig('output/generated/risk_chart.png', dpi=150) 3. 自动化部署 利用 cron (Linux) 或任务计划程序 (Windows),每天凌晨自动运行脚本,将最新报表推送到企业微信或钉钉群。结合 Git,可以将生成的报表提交到内部仓库,形成历史趋势对比。 4. 隐私保护 医疗数据敏感。在 data_processor.py 中增加脱敏逻辑,比如对 id 列进行哈希处理,确保速查手册中不包含任何可识别个人身份的信息。这是合规的底线。 小结 从学会语法到搭建项目,中间隔着的是工程化思维。今天这个抑郁症数据速查手册项目,虽然功能简单,但涵盖了数据清洗、模块化设计、自动化报表生成等核心技能。你不再是一个只会写片段的人,而是一个能交付完整解决方案的工程师。 这个项目可以直接作为你简历上的一个案例。它展示了你处理真实业务数据的能力,以及对细节(如数据清洗、边界处理)的关注。更重要的是,它解决了“学会语法却不知怎么搭项目”的焦虑。你有了模板,有了思路,接下来就是替换数据源,适应你的具体业务场景。 编程不是背代码,而是解决问题。当你能够用代码自动化地整理一份抑郁症筛查报告时,你就已经跨过了新手村。 你公司项目里是怎么处理的?欢迎评论