1. 医疗数据融合工程导论
医疗数据融合工程,是把分散在医院信息系统、检验设备、影像归档系统、可穿戴终端和科研数据库中的异构数据,经过采集、清洗、标准化、对齐、关联与治理,形成可用于临床辅助决策、科研分析和智能模型训练的统一数据资产。它既不是简单的数据搬运,也不是一次性脚本拼接,而是一项需要长期维护的工程能力。理解这一点,是进入本课程的第一前提。
多源医疗数据的类型与来源
从数据类型看,医疗数据大致可分为五类。第一类是结构化业务数据,如患者基本信息、诊断编码、医嘱、检验结果,通常来自 HIS、LIS、EMR,以关系表形式存储。第二类是半结构化数据,如 HL7 消息、JSON 格式的接口返回、XML 格式的病历文档。第三类是非结构化文本,如入院记录、病程记录、出院小结、病理报告。第四类是影像与信号数据,如 DICOM 影像、心电图、脑电图、监护波形。第五类是时序与设备数据,如可穿戴设备采集的心率、血氧、步数,以及呼吸机、输注泵的运行参数。
这些数据在真实环境中往往具有不同的时间粒度、编码体系和标识方式。例如,检验项目在不同医院可能使用不同的本地代码,患者标识在 HIS 中是住院号,在随访系统中可能是手机号或研究编号。融合的第一步,就是识别这些差异并建立可追溯的映射关系。
融合的价值与工程挑战
融合的价值体现在三个层面。在临床层面,把检验、影像、用药和监护数据关联后,可以更完整地还原患者状态,支持合理用药提醒和风险预警。在科研层面,多源数据整合能构建更丰富的队列特征,提高统计分析和模型训练的可靠性。在管理层面,跨系统数据打通有助于质控指标计算和资源调度。
但工程挑战同样突出。首先是标识不统一:同一患者在不同系统中可能有住院号、门诊号、医保号、研究编号,需要建立主索引。其次是时间对齐困难:检验报告有采样时间和报告时间,监护波形有毫秒级时间戳,用药记录只有日期,融合时必须明确以哪个时间轴为基准。第三是编码体系差异:诊断用 ICD-10,检验用 LOINC,药品用 ATC 或本地码,需要维护映射表。第四是数据质量参差:缺失、重复、单位不一致、逻辑矛盾普遍存在。第五是隐私与合规:患者标识必须脱敏,数据访问需要审计,跨机构共享要符合法规要求。
Python 技术栈全景
Python 在医疗数据融合中承担“胶水语言”和“分析引擎”双重角色。采集阶段常用 requests、httpx 调用接口,pymysql、psycopg2、SQLAlchemy 连接数据库,paho-mqtt 接入设备消息。处理阶段以 pandas、polars 为核心,配合 numpy 做数值计算,re 和 jieba 处理文本。影像与信号方面,pydicom 读取 DICOM,wfdb 读取生理信号。标准化与对齐可使用 fuzzywuzzy、rapidfuzz 做模糊匹配,datetime 和 pandas 做时间窗对齐。存储与调度方面,SQLAlchemy 管理关系库,pyarrow 和 parquet 管理列式文件,Airflow 或 Prefect 编排任务。质量校验可用 pandera、great_expectations。隐私保护可用 hashlib 做不可逆脱敏,cryptography 做加密传输。
下面给出一个最小可运行示例,演示如何把两份来源不同的患者数据按患者标识对齐,并检查时间字段的一致性。示例数据为教学假设数据,不是真实临床数据。
import pandas as pd
# 来源A:HIS 检验记录(假设数据)
lab = pd.DataFrame({
"patient_id": ["P001", "P002", "P003"],
"test_code": ["GLU", "GLU", "GLU"],
"value": [5.6, 7.2, 4.9],
"unit": ["mmol/L", "mmol/L", "mmol/L"],
"sample_time": ["2024-03-01 08:10", "2024-03-01 09:20", "2024-03-02 07:50"]
})
# 来源B:随访系统记录(假设数据)
followup = pd.DataFrame({
"patient_id": ["P001", "P002", "P004"],
"visit_time": ["2024-03-01 10:00", "2024-03-01 11:30", "2024-03-03 09:00"],
"note": ["空腹血糖偏高", "复查", "新入组"]
})
# 按 patient_id 内连接,只保留两边都存在的患者
merged = pd.merge(lab, followup, on="patient_id", how="inner")
# 时间差:随访时间 - 采样时间
merged["sample_time"] = pd.to_datetime(merged["sample_time"])
merged["visit_time"] = pd.to_datetime(merged["visit_time"])
merged["hours_diff"] = (merged["visit_time"] - merged["sample_time"]).dt.total_seconds() / 3600
print(merged[["patient_id", "value", "hours_diff", "note"]])
运行后可以看到,P001 和 P002 被保留,P003 因随访系统无记录被排除,P004 因检验系统无记录被排除。hours_diff 用于判断随访与检验是否在同一就诊窗口内。若时间差超过预设阈值(例如 24 小时),就需要人工确认是否属于同一次就诊。这个简单例子体现了融合工程的核心动作:标识对齐、时间对齐、质量判断。