信息速览
MGH/MF 波形库是 PhysioNet 上一份 2002 年上线的老资源,内容却比它的名字要"宽"得多。全名 Massachusetts General Hospital/Marquette Foundation Waveform Database,按字面读是"麻省总医院与 Marquette 基金会的波形数据库"——它把 MGH 和 MF 两个机构缩写拼在了一起,看上去像某个内部系统的代号,实际上是一份跨机构合作的公开数据。
它收录的不是心电图,而是病床边那台监护仪同时打出来的八路波形:三路心电,加上动脉压、肺动脉压、中心静脉压、呼吸阻抗与气道二氧化碳。二百五十位在重症监护病房、手术室与心导管室里接受监护的患者,每人一段十几分钟到八十余分钟的连续记录,信号被同步采样、同步存档、同步注释。
名字里最容易误读的一段是"MF"。它既不是文件格式也不是滤波方法,而是 Marquette Foundation 的缩写;而 MGH 虽然确实是那家医院,但这份库的意义不在医院的病历,而在于它把床旁监护仪的多路输出原封不动地留了下来(§1.2)。一屏速览见下表。
| 维度 | 内容 |
|---|---|
| 官方全名 | Massachusetts General Hospital/Marquette Foundation Waveform Database |
| 缩写拆解 | MGH = Massachusetts General Hospital;MF = Marquette Foundation |
| 中文名 | 麻省总医院/Marquette 基金会波形数据库 |
| 托管平台 | PhysioNet,Open Access 栏目 |
| 版本 | 1.0.0,2002 年 6 月 10 日发布 |
| DOI | 10.13026/C26K5Q |
| 患者数 | 250 名,记录名 mgh001 至 mgh250 |
| 每条通道数 | 8 路,头文件中按顺序定义 |
| 常规通道 | 三路心电、动脉压、肺动脉压、中心静脉压、呼吸阻抗、气道二氧化碳 |
| 附加通道 | 部分记录含颅内压、左房压、心室压、主动脉内球囊压 |
| 采样率 | 每秒 360 个样本,有符号 12 位量化为 16 位存放 |
| 单条时长 | 十余分钟至八十余分钟,多数约一小时 |
| 注释 | 每记录一份 .ari,含心搏与事件两类标签 |
| 整包大小 | 未压缩约 4.2 GB |
| 许可 | Open Data Commons Attribution License v1.0 |
| 引用文献 | Welch JP 等,J Clinical Monitoring 7(1):96-97,1991 |
§1 它要解决的具体麻烦
1.1 单参数数据永远回答不了"当时整个人是什么状态"
心电算法在 MIT-BIH 这类单参数库上做到九成以上灵敏度,几乎是十几年前的常规成绩。可一进重症监护病房,同一条 QRS 就未必还能被认出来:患者可能在用呼吸机,可能在注射升压药,可能刚做完冠脉造影,身上插着四五根导管,还连着主动脉内球囊反搏。心电的形态、心率、血压、中心静脉压是同时变化的,只看一路信号,无法判断某次心率骤降是房室传导阻滞还是血管张力崩塌。
这就是多参数同步记录的价值所在。它让研究者能把"心电异常"与"血流动力学后果"放在同一根时间轴上对照:一个室性早搏出现的同时,动脉压的波峰是否塌了一截;气管插管的那一刻,呼吸阻抗和二氧化碳曲线各自怎么变;气囊反搏开着和关掉,压力曲线的形态差在哪里。
MGH/MF 就是这种思路的早期实现。它从上世纪九十年代初开始采集,把监护仪上的模拟输出直接录在磁带上,再整体数字化。介质是磁带和 CD-ROM,格式是 WFDB——这套格式后来成了 PhysioNet 的标准,所以在 2002 年上线时,它几乎不需要转换就能被现成工具读取(§8.1)。
1.2 三条常见的错误期待
第一条,把 MGH 当成"麻省总医院内部病历数据库"。 名字里带着医院名,很容易让人以为这是一份院内电子病历导出。实际它是床旁监护的波形记录,没有病历文本、没有检验结果、没有出院诊断编码。头文件里有年龄、性别和一句诊断,但那是注释,不是结构化字段。
第二条,把 MF 当成文件格式或滤波方法。 MF 是 Marquette Foundation,一个与麻省总医院合作做监护技术研究的基金会。它不出现在数据文件里,只出现在库名和引用文献里。把它读成 Motion Filter 或某个信号处理缩写,会让整段数据描述的逻辑错位。
第三条,把八路当成八导联。 八路里只有三路是心电,另外五路是压力和气流信号。把它们当成八导联心电去画心电向量,得出的东西没有任何生理意义。头文件里的通道名写得很直白:ECG lead I、ART、PAP、CVP、Resp. Imp.、CO2,前三个和后五个不是一类。
1.3 它能给到的与给不到的
| 你的需求 | 它给的 | 够不够 |
|---|---|---|
| 多参数同步信号的研究材料 | 每记录 8 路同步波形,心电与压力、呼吸、气体同轴 | 够,这是主用途 |
| 心搏检测算法的鲁棒性评测 | 250 段真实监护波形,含起搏、室性早搏、传导阻滞 | 够,但需自行划分 |
| 压力波形与心电的因果分析 | ART、PAP、CVP 与心电同步、时间对齐 | 够,注释里还有置零与标定事件 |
| 现代重症患者的人群代表性 | 1990 年代初、单中心、250 人 | 不够,人群构成已过时 |
| 端到端深度学习训练 | 记录长短不一、通道有效性参差 | 勉强,需要大量清洗 |
| 十二导联心电研究 | 只给三路,且第三路只写 V | 不够,无法重建十二导联 |
| 个体化血流动力学建模 | 三路压力加心电,足以驱动简化模型 | 够,是常见用法之一 |
| 呼吸与循环耦合研究 | 呼吸阻抗与气道二氧化碳两路均保留 | 够,这在其它库中少见 |
| 临床决策或预后预测 | 无转归、无用药记录、无结构化诊断 | 不够,结构上做不到 |
1.4 你的处境与它能帮到的事
| 你的处境 | 它能帮你什么 | 下一步该做什么 |
|---|---|---|
| 你在做多参数心电算法,只有单导联数据可用 | 提供心电与压力、呼吸信号的同步对照,验证算法在监护场景下的稳定性 | 先在干净段跑通,再切到含起搏与室早的段做压力测试 |
| 你在研究呼吸对心率与血压的调制 | 呼吸阻抗与气道二氧化碳两路可直接作为呼吸参考 | 用阻抗包络提取呼吸相位,与心电 RR 序列做锁相分析 |
| 你在给机械循环支持装置搭测试台 | 真实的主动脉压与心室压波形可用于驱动仿真回路 | 提取若干典型段的压力轨迹作为边界条件 |
| 你在做波形生成或重建 | 250 段八路真实信号,足以训练从心电推压力的模型 | 先用同一患者的通道配对建模,再试跨患者迁移 |
| 你在教学,需要展示监护仪输出长什么样 | 头文件里连标定脉冲、压力置零、导管冲洗都有注释 | 取一段含导管操作的事件时间线做讲解 |
| 你有一个现代大库,需要一份"老数据"做外部对照 | 采集年代、设备、人群都不同,天然构成时代对照 | 明确写清代际差异,不要把差异读成模型退化 |
| 你只想找一份十二导联心电 | 不是这份 | 换库内其它心电词条 |
1.5 一句话判断
它是一台三十年前床旁监护仪的存档切片:八路波形同轴录下,事件按分钟标好,既够真实,也够旧。
1.6 不适合谁:四条边界
不适合做现代人群的统计推断。 二百五十名患者来自一家医院的一个时间段,没有抽样设计,也没有加权。任何"某类患者在重症监护中的占比"之类的问题,在这份数据上得到的答案只属于当年那批人。
不适合替代十二导联心电。 三路心电分别是肢体导联 I、II 和一路标为 V 的胸前导联。第三路在多数记录里只写 ECG lead V,具体是 V1 还是 V5,头文件没有逐条交代。想研究 ST 段改变在十二导联上的分布,这份库给不了。
不适合做临床决策类模型。 没有结局变量,没有出院状态,没有用药剂量。能建模的只有波形本身的形态与关联,不能建模"这样监护下去会怎样"。
不适合把通道位置当常量。 部分记录的第 5 至第 8 路被写成 No signal 或 Pressure 这类笼统名字,实际插的是哪根导管要回读注释里的事件时间线才知道(§2.2)。默认"第 4 路一定是动脉压"的代码,在这份库上会静默读到别的信号。
§2 数据构成与规格
2.1 一个扁平目录,一份清单,一套 WFDB 三件套
解压后没有按患者或年份划分的子目录,二百五十条记录平铺在同一层。每条记录由三个文件组成:.hea 头文件是纯文本,第一行写记录名、通道数、采样率与样本总数,随后每个通道一行;.dat 是二进制数据体,八路信号按帧交错存放;.ari 是注释文件,用 WFDB 的注释二进制格式,每条记录一个样本位置和一个标签。
目录里另有一份 RECORDS 清单,每行一个记录名,共二百五十行;一份 ANNOTATORS 声明注释类型为 ari,含义是心搏与事件;以及一份 2019 年补入的 SHA256SUMS.txt 校验文件。没有 README,没有数据字典,也没有患者分层表——所有临床信息都塞在头文件的注释行里。
| 层级 | 文件 | 数量 | 说明 |
|---|---|---|---|
| 目录 | 根目录 | 1 | 全部记录平铺,无子目录分流 |
| 头文件 | mghNNN.hea |
250 | 文本,含通道与患者描述 |
| 数据体 | mghNNN.dat |
250 | 二进制,8 路交错,12 位有效 |
| 注释 | mghNNN.ari |
250 | 心搏与事件标签 |
| 清单 | RECORDS |
1 | 二百五十行记录名 |
| 注释声明 | ANNOTATORS |
1 | 声明 ari 的含义 |
| 校验 | SHA256SUMS.txt |
1 | 逐文件哈希 |
| 遗留目录 | cape |
1 | CAPE 患者模拟器的软件与文档 |
cape 目录值得单独说一句。它装的是 CAPE(Computer Aided Patient Emulator),当年数据库设计者写的一套系统,能把存下的波形从 PC 上按实时速度回放出来,用于教学与设备测试。PhysioNet 保留了仅软件的演示版本,并注明含 ISA 总线板卡的完整版需另外向 Cardionics 索取。今天这个目录对多数使用者没有用,但它解释了为什么这个库的头文件里有那么多标定事件——那套回放系统需要标定值才能还原物理量。
2.2 字段与记录的完整字典
这个库没有数据库表,信息分散在两处:头文件的固定格式行,与随后的注释行。固定格式行是给解析器读的,注释行以 # 开头,是给人读的自由文本。下表把两类信息合并列出。
| 信息项 | 存放在哪 | 取值或范围 | 是否每条都有 |
|---|---|---|---|
| 记录名 | 头文件第一行 | mgh 加三位流水号 | 全部 |
| 通道数 | 头文件第一行 | 8 | 全部 |
| 采样率 | 头文件第一行 | 360/0.476,即每秒 360 样本 | 全部 |
| 样本总数 | 头文件第一行 | 六位数至七位数 | 全部 |
| 起始时间 | 头文件第一行 | 时:分:秒 与 日/月/年 | 多数记录有 |
| 通道文件名 | 通道行 | 统一指向同名 .dat | 全部 |
| 格式码 | 通道行 | 212,12 位有符号 | 全部 |
| 增益与基线 | 通道行 | 每通道不同,如 12/mV 或 10/mmHg | 全部 |
| 初始值 | 通道行 | 该通道首样本值 | 全部 |
| 通道描述 | 通道行末 | ECG lead I、ART、PAP、CVP 等 | 全部,部分为 No signal |
| 年龄 | 注释行 | <age> 后两位数 |
多数记录有 |
| 性别 | 注释行 | <sex> 后 M 或 F |
多数记录有 |
| 诊断 | 注释行 | <diagnoses> 后一句英文 |
多数记录有 |
| 病史 | 注释行 | PERTINENT HISTORY 段 |
部分记录有 |
| 心律 | 注释行 | UNDERLYING RHYTHM 段 |
多数记录有 |
| 心电判读 | 注释行 | ECG INTERPRETATION 段 |
部分记录有 |
| 血流动力学数值 | 注释行 | HEMODYNAMIC DATA 段,如 ART 140/50 |
部分记录有 |
| 呼吸参数 | 注释行 | 频率与通气模式 | 部分记录有 |
| 事件时间线 | 注释行 | PROCEDURAL EVENTS 段,按分钟列 |
心导管类记录多见 |
| 心搏标签 | .ari 注释 | 逐搏位置与类型 | 全部 |
注释行的写法是自由文本,不是键值对。年龄和性别用尖括号包裹的字段名,方便用正则提取;其余段落只靠大写小节标题分隔。这意味着想做结构化统计,第一件事是写一套容错的正则,而不是直接 read_csv。
2.3 一条记录的完整解剖
以 mgh001 为例。头文件第一行写着 mgh001 8 360/0.476 1376831,按采样率换算,这条记录长约 63.7 分钟。随后八行通道定义依次是:心电 I、心电 II、心电 V、动脉压、肺动脉压、中心静脉压、呼吸阻抗、气道二氧化碳。注释行给出年龄 80、性别女、诊断为颈动脉内膜剥脱术,心律是先天性完全性心脏传导阻滞伴交界性逸搏心律,心率约每分钟 40 次。
mgh001 8 360/0.476 1376831
mgh001.dat 212 1167(-127)/mV 12 0 -1949 1271 0 ECG lead I
mgh001.dat 212 1208(-573)/mV 12 0 -1951 50883 0 ECG lead II
mgh001.dat 212 1121(-1070)/mV 12 0 -1955 64363 0 ECG lead V
mgh001.dat 212 12.06(-1215)/mmHg 12 0 -869 44555 0 ART
mgh001.dat 212 20.72(-1015)/mmHg 12 0 1023 11090 0 PAP
mgh001.dat 212 20.08(-1006)/mmHg 12 0 -1537 53636 0 CVP
mgh001.dat 212 1000 12 0 -784 47520 0 Resp. Imp.
mgh001.dat 212 1000 12 0 -258 35980 0 CO2
通道行的第二位是格式码,212 表示每样本占 12 位、以左对齐存放在 16 位字里;第三位是增益与基线,例如动脉压写作 12.06(-1215)/mmHg,意思是每毫米汞柱对应十二点零六个数字单位,基线偏移为负一千二百一十五;末位是通道描述。呼吸阻抗与二氧化碳两路的增益写的是 1000 且没有单位,表示这两路没有可换算的生理量纲,只能做相对变化使用。
注释文件则是完全不同的形态。它是一串二进制记录,每条占两个字节,低十位是时间差,高六位是标签索引。用注释工具读出来,最初的几十条是这样的:
15 c calibration pulse
17 # pressure line flushed
20 x signal source change
21 w wedge recording (PCW)
23 * pop test
24 z zero pressure
NO CO2 DATA
ALL ZEROS
DATA ON
数字是自上一条起算的样本偏移,中间那个字符是标签,后面是注释器清单里对应的英文说明。心搏标签与这些事件标签混在同一个文件里,靠标签字符区分:心搏用常规的 N、V、A 这类符号,事件用 c、z、* 这类标点符号。
2.4 通道的有效性与三种记录形态
八路并不是每条记录都满。按头文件里的通道描述分,记录大致有三种形态。
| 形态 | 通道描述特征 | 典型记录 | 使用时的注意事项 |
|---|---|---|---|
| 标准监护 | ECG I/II/V 加 ART、PAP、CVP、Resp. Imp.、CO2 | mgh001、mgh100、mgh175 | 八路齐全,可直接按名索引 |
| 导管室 | ECG 三路加多个 Pressure 或 Pressure1/2 |
mgh210 | 压力路含义需回读事件时间线 |
| 缺损 | 若干路写成 No signal |
mgh050、mgh250 | 该路为占位,不可当信号使用 |
No signal 是官方自己写在通道描述里的标记,不是解析失败。它的出现意味着当时那根导管没接、传感器没开,或者监护仪对应通道被关掉了。把它当零值参与平均,会得到一段"血压恒为零"的假象。Pressure 这类笼统命名则更麻烦:mgh210 的第 4 至 7 路都叫 Pressure 或 Pressure1/2,实际插的是右心导管的不同节段,要看事件时间线里"PA INSERTION""CATHETER IN PA OUTFLOW TRACT"这类记录才能推断。
2.5 与同类多参数资源的规格差异
公开库里同时存心电与血压的不多,能同时存肺动脉压与气道二氧化碳的更少。下表把本库与库内几条相近记录的规格并列,只比结构,不比质量。
| 维度 | MGH/MF 波形库 | 多数公开心电库 | 单参数压力库 |
|---|---|---|---|
| 主信号 | 心电加五类压力与气流 | 仅心电 | 仅一类压力 |
| 同步路数 | 8 | 1 至 12 | 1 至 2 |
| 采样率 | 360 Hz | 250 至 1000 Hz | 常为 100 至 250 Hz |
| 量化解位 | 12 位存 16 位 | 常为 16 位 | 常为 12 至 16 位 |
| 注释内容 | 心搏加导管与标定事件 | 多为心搏与节律 | 少见注释 |
| 单条时长 | 十余分钟至八十余分钟 | 数十秒至数分钟 | 数分钟 |
| 采集场景 | 重症、手术室、导管室 | 门诊或 Holter | 多为术中或监护 |
| 是否含呼吸参考 | 是,阻抗与二氧化碳两路 | 否 | 否 |
这张表解释了一个常被忽略的事实:本库的 360 Hz 采样率在压力信号上完全够用,在心电上则偏低。常规心电分析在 250 至 500 Hz 之间都能工作,但要做高频成分(如心室晚电位)就不足。选它之前先想清楚要不要高频——要,就换库。
记录名本身就是唯一的主键,中间不要试图从文件名推出患者编号或日期。流水号只是编号,不保证与采集时间同序:相邻的两条记录,采集日期可能相差两个月。头文件第一行的日期字段才有时间意义,且不是每条都有。
mgh175 8 360/0.476 1257872 6:09:01 05/09/1991
这一行的最后两段是记录起始与日期。日期格式为日/月/年,别按美式的月/日/年去读,否则同一条记录会凭空差出大半年。这一点在跨库合并时间轴时尤其容易踩。
§3 它的身份:一份监护仪输出的集体存档
3.1 谁做的、在哪做的、为什么做
官方页面写明,这份库是麻省总医院的医师、生物医学工程师与护士合作的成果,记录来自重症监护病房、手术室与心导管室三类场景。主页的致谢里点名感谢该院的 Jeffrey Cooper 与 Penny Ford-Carleton,两人负责安排把这些录音通过 PhysioNet 公开。
这是一个典型的"院内工程团队加临床科室"的组合产物:临床方提供场景与判读,工程方负责采集与数字化,护士负责在记录过程中标注事件。三方分工直接体现在数据结构上——波形是工程方的产物,注释里的心律判读是临床方的产物,事件时间线里的"导管置入"“标定”"冲管"是护士与技师的产物。
3.2 时间线:从磁带、CD-ROM 到开放下载
| 时间 | 事件 | 依据 |
|---|---|---|
| 1991 | 库的介绍文章发表于 J Clinical Monitoring 第 7 卷第 1 期 | 官方引用 |
| 1991 年 7 至 9 月 | 头文件事件时间戳可见的采集月份 | 样例头文件 |
| 1993 年 7 月 | 数据体与注释文件的文件时间 | 官方文件列表 |
| 2002 年 6 月 10 日 | PhysioNet 以 1.0.0 版发布 | 官方页面 |
| 2017 年 1 月 3 日 | 五个头文件的信号长度被修正,一个数据体被截断四位 | 官方更新说明 |
| 2019 年 2 月 20 日 | 补入 SHA256 校验文件 | 官方文件列表 |
2017 年那次修订值得记下来。官方说明 mgh026、mgh175、mgh196、mgh199、mgh210 五个头文件里的信号长度与实际数据体大小不符,已更正;同时 mgh210 的数据体被截去四位。这是一次数据层面的更正,意味着在此之前的版本上,这五条记录读出来会长度不齐。版本号仍然是 1.0.0,所以引用时只写版本号不足以定位到修订前后,最好同时写下载日期。
3.3 采集现场:一台监护仪、一根磁带、八个通道
按官方描述,原始信号录在八通道仪表磁带上,回放时以两倍实时速度数字化。原始采样率为每路每秒 1440 个样本,回放时按二倍抽取,得到相对实时的每秒 360 个样本。
这种"先录带、再高速回放"的做法在当年是常态:磁带机便宜、容量大、不受计算机存储限制,而两倍速回放可以把数字化时间减半。代价是必须靠抗混叠把抽取前的带外成分压掉,官方说明用的是低阶模拟抗混叠加高阶数字 FIR 抗混叠的组合,目的是减小相位失真。头文件在同目录下给出 FIR 系数文件 sample8.hea 作为参考。
对使用者来说,这段历史有两个直接后果。其一,所有记录的时间轴是"相对于实时"的,360 Hz 不是任意选的整数,而是 1440 除以 2;按 360 Hz 算出来的每分钟样本数恰好是 21600。其二,通道之间的相位关系是设计过的,同一时刻的心电与动脉压不存在回放错位,跨通道做时序分析是安全的(§4.4)。
3.4 受试者是谁:三类场景、二百五十段监护
官方只给出总数与场景类别,没有给出按场景的分布、按年龄的分布,也没有给出病种构成表。从头文件能读到的个体信息是年龄、性别与一句诊断,这三项多数记录都有,但不是全部。
| 场景 | 官方表述 | 头文件里能见到的线索 |
|---|---|---|
| 重症监护病房 | 稳定与不稳定患者的床旁监护 | 呼吸机参数、持续泵入药物的事件行 |
| 手术室 | 术中血流动力学监测 | 麻醉与体位相关事件行 |
| 心导管室 | 右心与左心导管、冠脉造影 | PA INSERTION、PCW、wedge 等事件 |
心导管室这一类在头文件里最"吵":事件时间线按分钟罗列,从"SET-UP"开始,一路写下去,中间夹着压力置零与导管位置变化。mgh210 就是这种形态,注释里先写右心导管、左心导管与冠脉造影,再写"起搏心律"“永久性起搏器”,最后逐分钟列出导管操作。这类记录对研究压力波形的解读特别有用,因为每一次压力变化都能对上一次操作。
3.5 与库内其它 PhysioNet 重症资源的对照
| 资源 | 与本库的关系 | 主要差异 |
|---|---|---|
| MIMIC 系列波形库 | 同属重症多参数,但年代与规模不同 | 现代、多中心化程度更高、需资格审核 |
| MIT-BIH 心律失常库 | 同属心电,注释体系一脉相承 | 单参数、双导联、以心律失常分类为目标 |
| 各类床旁压力库 | 部分仅含动脉压 | 本库压力路更多、且有呼吸与气体参考 |
| 各类心音与呼吸音库 | 声学信号,不同模态 | 不可直接比较 |
需要强调的是,本库与现代重症数据库之间不是替代关系。MIMIC 一类资源覆盖的是近年、带完整病历与结局的重症患者,本库覆盖的是三十年前的纯波形。前者适合做预测建模,后者适合做信号层面的机制分析。把两者放在一篇论文里,恰当的说法是"跨时代对照",而不是"外部验证"。
3.6 注释里那几张"手写标签"
头文件的注释段并不统一。有的记录先写 <age>/<sex>/<diagnoses> 一行摘要,再分段写病史、心律、心电判读、血流动力学数值、呼吸参数、操作事件;有的记录只有前一两段,后面直接接事件时间线;也有记录把心电判读拆成"基础心律"“节律紊乱”"心电图判读"三小段。
| 注释小节 | 英文标题 | 记录中出现的频率 | 内容性质 |
|---|---|---|---|
| 摘要行 | <age> / <sex> / <diagnoses> |
多数 | 一行式人口学与诊断 |
| 病史 | PERTINENT HISTORY |
部分 | 与本次监护相关的既往史 |
| 基础心律 | UNDERLYING RHYTHM |
多数 | 主心律与心率估计 |
| 节律紊乱 | RHYTHM DISTURBANCES |
部分 | 早搏、心动过速等 |
| 心电判读 | ECG INTERPRETATION |
部分 | 肥大、传导阻滞、ST-T 改变 |
| 起搏信息 | PACEMAKER INFORMATION |
少数 | 起搏器类型与工作模式 |
| 血流动力学 | HEMODYNAMIC DATA |
部分 | 各腔室的收缩压与舒张压 |
| 呼吸参数 | RATE / MODE OF VENTILATION |
部分 | 呼吸频率与通气模式 |
| 波形特征 | WAVEFORM PATTERNS |
少数 | 定性描述,如炮波、肺动脉高压 |
| 操作事件 | PROCEDURAL EVENTS |
导管室类多见 | 按分钟罗列的操作与状态变化 |
这张表不能当字段清单用,只能当"可能的段落"清单用。真实记录里小节的顺序与是否出现都不固定,写解析器时应当按关键词扫描,而不是按行号定位。以 mgh001 为例,它把基础心律写成"先天性完全性心脏传导阻滞伴交界性逸搏心律,约每分钟四十次",把波形特征写成"房室不同步导致中心静脉压炮波、肺动脉压逆向炮波效应、肺动脉高压"——这两句已经是判读结论,不是原始测量值。
WAVEFORM PATTERNS 这一小节是这份库最特别的地方。它把"波形长什么样"用临床语言写下来,而不是用数字。对做波形生成或形态学分析的人来说,这几句相当于现成的弱标注:它告诉你这一段里存在某种可辨识的形态,而具体位置要靠自己找。
§4 它最独特的东西:八路同轴与分钟级事件
4.1 为什么"同步多参数"比"高采样率"更稀缺
公开心电库里,采样率做到 1000 Hz 的不在少数,做到 12 导联的也不少。但把心电、动脉压、肺动脉压、中心静脉压、呼吸阻抗、气道二氧化碳这六类信号同时录下、同时对时、同时注释的,寥寥无几。
原因不难理解。高采样率只需要换一块采集卡;同步多参数需要患者身上真的插着这些导管,而且这些导管在整段记录期间要一直可用。肺动脉压导管需要右心导管到位,中心静脉压需要颈内或锁骨下置管,气道二氧化碳需要接在呼吸机回路上。任何一路脱落,记录就缺一块。这也解释了为什么本库里 No signal 那么常见——记录长度动辄一小时,中间有导管移位、冲洗、换传感器,在所难免。
4.2 案例:mgh001 这条记录的三层信息
§4.2 的案例取 mgh001,原因是它把三种信息层次同时暴露出来,适合当作读库的样板。第一层是通道结构:八路齐全,没有 No signal,前三路是心电,后五路是压力、阻抗与气体。第二层是临床背景:八十岁女性,颈动脉内膜剥脱术,先天性完全性心脏传导阻滞,交界性逸搏心律约每分钟四十次,伴单灶室性早搏与左房、左室肥厚。第三层是波形细节:中心静脉压曲线上出现"炮波",官方注释明确指出这是房室不同步造成的,并且这种效应还逆向传到了肺动脉压曲线上。
import wfdb
rec = wfdb.rdrecord("mgh001", pn_dir="mghdb/1.0.0")
ann = wfdb.rdann("mgh001", "ari", pn_dir="mghdb/1.0.0")
print(rec.sig_name)
print(rec.fs, rec.sig_len, round(rec.sig_len / rec.fs / 60, 1), "min")
print(ann.sample[:8], ann.symbol[:8])
这段代码给出三个可以直接引用的量:通道名列表、采样率与样本总数、以及前八条注释的位置与标签。把样本总数除以 360 再除以 60,就得到以分钟计的时长;把注释位置除以 360,就得到以秒计的事件时刻。§4.2 的案例之所以适合当样板,是因为它三段信息都能用同一套代码抽出来,不需要额外的临床字典。
4.3 炮波:一份注释把三路信号串起来
中心静脉压上的"炮波"(cannon wave)是房室不同步的经典征象:心房收缩时三尖瓣关闭,血液回顶到腔静脉,压力曲线上出现一个异常高的 a 波。在这条记录里,患者的房室传导完全阻断,心房与心室各按自己的节律跳,于是炮波以一定的周期出现。官方注释还补了一句:这个效应在肺动脉压曲线上也能看到反向的痕迹。
这句话的价值在于它把三个通道的关系讲清楚了。中心静脉压与肺动脉压都是压力通道,但它们的压力来自不同腔室,正常情况下不应有这种同步的异常。当房室不同步时,右侧心房的压力波动会沿着静脉系统与右心室传下去,在两路压力上留下可以互相对照的痕迹。只看中心静脉压一路,会以为是导管问题;三路同看,才能把它归因到节律上。
4.4 它能支撑的四类实验
| 实验类型 | 需要的数据条件 | 本库是否满足 | 常见做法 |
|---|---|---|---|
| 从心电推压力 | 心电与至少两路压力同步 | 满足 | 用同一段做输入输出配对 |
| 多模态心搏检测 | 心电质量不稳、需压力补充 | 满足 | 心电与动脉压联合判决 |
| 呼吸—循环耦合 | 呼吸参考与心电、血压同步 | 满足 | 阻抗提取呼吸相位,对齐 RR |
| 器械测试与仿真 | 真实压力轨迹作为边界条件 | 满足 | 抽取典型段驱动测试台 |
四类实验里,第三类是最少被其它库替代的。呼吸阻抗信号在常规心电库里根本不存在,而在本库中它与心电、血压严格同轴。研究呼吸性窦性心律不齐、机械通气对血压变异的影响,这路阻抗是免费的呼吸相位参考(§9.2)。
4.5 边界条件:什么时候它不再适用
当问题涉及高频心电成分时。 360 Hz 的采样率意味着可分析带宽上限在 180 Hz 附近,实际因抗混叠还会更窄。心室晚电位、高频 QRS 这类研究需要 1000 Hz 以上的采样,本库做不到。
当问题涉及人群差异时。 二百五十人、单中心、特定年代,任何"不同人群之间"的比较都缺少足够的组容量。想比较男女、年龄层或病种的差异,样本量会迅速掉到两位数,结论不稳。
当问题涉及临床结局时。 没有结局变量。可以研究波形与波形的关系,不能研究波形与"后来怎样"的关系。
当问题涉及精确的绝对血压时。 压力通道有标定值,但标定质量依赖当时的操作。头文件里的压力置零、标定脉冲事件说明这一路曾被校准过,但没有留下校准误差的量化记录。做绝对压力分析,应先检查每条记录的增益与基线是否与事件时间线一致(§7.3)。
4.6 用注释里的"事件"做弱监督
.ari 里的非心搏记录本身就是一种信号:z 表示压力置零,c 表示标定脉冲,# 表示管路冲洗,w 表示楔压记录。这些事件在波形上都会留下特征——置零瞬间压力曲线出现台阶,标定期间出现方波,冲洗时出现高频尖峰。于是就有了一个不需要逐点标注的弱监督任务:先定位事件,再判断它属于哪一类。
| 事件标签 | 含义 | 波形上的典型痕迹 | 可做的任务 |
|---|---|---|---|
c |
标定脉冲 | 数秒长的方波平台 | 自动识别标定段并剔除 |
z |
压力置零 | 压力基线出现阶跃 | 基线漂移的分段归因 |
# |
管路冲洗 | 短时高频扰动 | 伪迹检测的阳性样本 |
w |
楔压记录 | 压力波形振幅与形态改变 | 楔压段识别 |
* |
pop test | 短促的过冲 | 传感器动态响应检查 |
这张表的价值在于它指出了这份库的一个非常规用法:它不仅能做心电与血压的分析,还能做监护仪操作流程的识别。这类任务在别的库里几乎没有现成材料,因为别的库不保留操作事件。
§5 怎么拿到:从目录遍历到可训练张量
5.1 目录与体积
整库未压缩约 4.2 GB。其中有 250 个头文件(每个 1 至 2 KB)、250 个数据体(小的十一兆余,大的二十余兆)、250 个注释文件(十几到六十余 KB),另加 cape 目录与清单文件。数据体的大小与记录长度近似成正比,八路十二位交错存放意味着每秒约 360 帧、每帧十六字节,即每秒约 5.8 KB,一小时约 20 MB。
5.2 批量获取
三种方式都能拿到同一份内容,一条命令即可。
#-- 方式一:整包下载(4.2 GB)
wget -c https://physionet.org/content/mghdb/1.0.0/mghdb.zip
#-- 方式二:递归抓取目录(只下载需要的部分时可加 --cut-dirs)
wget -r -N -c -np https://physionet.org/files/mghdb/1.0.0/
#-- 方式三:从公开桶同步(无需 AWS 账号)
aws s3 sync --no-sign-request s3://physionet-open/mghdb/1.0.0/ ./mghdb
第三种方式对脚本化流水线最友好:不必先整包落地再解压,也不会因为单次 HTTP 中断而前功尽弃。若只需要若干条记录,可以直接按文件名抓取,例如只取头文件和注释先做索引,再按需拉数据体。
5.3 建立索引
头文件里的注释行是非结构化文本,索引的价值在于把年龄、性别、诊断、通道名抽成列,供后续筛选。
import re
from pathlib import Path
def parse_header(path):
lines = Path(path).read_text(encoding="utf-8", errors="replace").splitlines()
head = lines[0].split()
chan = [l.split()[-1] for l in lines[1:1 + int(head[1])]]
body = "\n".join(lines[1 + int(head[1]):])
age = re.search(r"<age>:\s*(\d+)", body)
sex = re.search(r"<sex>:\s*([MF])", body)
dx = re.search(r"<diagnoses>:\s*(.+)", body)
return {
"name": head[0],
"fs": head[2].split("/")[0],
"n": int(head[3]),
"chan": chan,
"age": int(age.group(1)) if age else None,
"sex": sex.group(1) if sex else None,
"dx": dx.group(1).strip() if dx else None,
}
rows = [parse_header(p) for p in sorted(Path("mghdb").glob("mgh*.hea"))]
print(len(rows), rows[0]["chan"][:3])
索引里最该保留的是 chan 这一列。它决定了后面对每条记录能做哪几路分析,也决定了哪些记录要因为 No signal 被排除在外。建索引时顺手把通道名归一化成 ecg1、ecg2、ecg3、art、pap、cvp、imp、co2 这八个代号,后面的代码就不必再关心原始拼写的大小写与空格差异。
5.4 切窗与张量
记录长短不一,直接堆成张量需要一个共同的窗长。重症波形分析的常用窗在十秒到六十秒之间:太短则压力波动的低频成分被切掉,太长则计算量上去而对判决帮助不大。
import numpy as np
def windows(rec, win_sec=30, step_sec=15):
fs = rec.fs
L, S = int(win_sec * fs), int(step_sec * fs)
x = rec.p_signal
out = []
for i in range(0, x.shape[0] - L + 1, S):
w = x[i:i + L].astype("float32")
if np.isnan(w).any():
continue
out.append(w)
return np.stack(out) if out else np.zeros((0, L, x.shape[1]))
p_signal 是已经按增益与基线换算过的物理量,单位随通道而定:心电是毫伏,压力是毫米汞柱,阻抗与二氧化碳没有单位。把不同单位的通道直接送进同一个网络,需要先各自标准化;按通道分别减均值除标准差,比整体标准化更稳。呼吸阻抗与二氧化碳两路的增益写成 1000 且无单位,标准化处理对它们几乎是必需的。
5.5 按场景与通道可用性分组的评测协议
直接随机切分会让同一条记录的不同窗同时出现在训练与测试里,评估结果虚高。更合理的切分单位是记录号,且应先按通道可用性分层。
| 分层依据 | 分层方式 | 目的 |
|---|---|---|
| 记录号 | 按流水号划训练、验证、测试 | 避免同患者泄漏 |
| 通道完整性 | 八路齐全与有缺损分两池 | 保证评测输入同构 |
| 场景 | 监护、手术室、导管室 | 检验跨场景泛化 |
| 注释密度 | 按 .ari 标签数量分档 | 避免训练集被长记录主导 |
第一层最容易做,也最容易漏。同一条 60 分钟记录切成 240 个三十秒窗,若随机分配,测试集里几乎必然出现与训练集相邻的窗,因为相邻窗共享绝大部分样本。按记录切分之后,测试集的样本数会少很多,但结论可信。
5.6 六个最容易出错的地方
其一,把 No signal 当信号读。 该通道在整段里恒为零,参与任何统计都会拉低均值。建索引时就该标记出来。
其二,按位置索引通道。 不同记录的第 5 路可能是肺动脉压,也可能是某个未命名的 Pressure。一律按名字索引,名字缺失时才回退到位置,并在日志里记一笔。
其三,忽略 2017 年的长度修订。 下载的是 2017 年之后的文件则无此问题;若用了旧镜像,mgh026、mgh175、mgh196、mgh199、mgh210 五条会读出错位。
其四,用 360 Hz 做高频分析。 详见 §4.5。
其五,把注释里的所有记录都当心搏。 .ari 里混着标定、置零、冲管、换源这些事件标签,直接按位置取 RR 间期会算出一堆假的短间期。取 RR 前先用标签字符把事件记录滤掉。
其六,把记录时长当固定值。 短的三十余分钟,长的八十余分钟,按固定长度切窗时末尾会剩下一截。要么丢弃,要么补齐后标记,不要静默截断。
5.7 一个能跑通的压力—心电对齐检查
多参数分析的第一步不是建模,而是确认两路信号在时间上真的对齐。做法很简单:取一段一分钟的数据,找心电 R 波位置,再在这些位置上叠加动脉压,看脉压波峰是否稳定落在 R 波之后的一段固定延迟内。
import numpy as np
import wfdb
rec = wfdb.rdrecord("mgh100", pn_dir="mghdb/1.0.0")
ann = wfdb.rdann("mgh100", "ari", pn_dir="mghdb/1.0.0")
idx = {n: i for i, n in enumerate(rec.sig_name)}
ecg = rec.p_signal[:, idx["ECG lead II"]]
art = rec.p_signal[:, idx["ART"]]
beats = ann.sample[ann.symbol == "N"]
beats = beats[(beats > rec.fs) & (beats < len(ecg) - rec.fs)]
lags = []
for b in beats[:200]:
seg = art[b:b + int(0.6 * rec.fs)]
if seg.size:
lags.append(int(np.argmax(seg)))
print(len(lags), float(np.median(lags)), float(np.std(lags)))
输出的中位数是脉压波峰相对 R 波的延迟,单位是样本。正常人这一延迟在百来个样本量级且波动很小;若中位数异常或标准差很大,多半是通道取错了,或者这一段的动脉压管刚冲洗过。这个检查只要两分钟,却能挡掉后面几小时的无效分析。
§6 与库内词条的关系
6.1 关系图谱
这份库在库内处在"重症多参数"与"早期心电"两个标签的交界处。它与心律失常分类类词条的关系是注释体系的同源,与多参数类词条的关系是场景的同源。
| 关系类型 | 相关词条方向 | 具体关系 |
|---|---|---|
| 注释体系 | MIT-BIH 心律失常库 | 同一套 WFDB 注释机制,标签风格相近 |
| 场景 | 重症与监护类波形资源 | 同为床旁多参数,但年代更早 |
| 信号类型 | 动脉压、肺动脉压类资源 | 本库压力路更全,且带呼吸参考 |
| 平台 | PhysioNet 其它 Open Access 资源 | 同平台、同许可、同取数方式 |
| 年代 | 早期心电库 | 同为上世纪九十年代前后的采集 |
6.2 检索路径
若你想找的是"一份能同时看到心电与血压的数据",路径是从生理信号类目进,再按"多参数"筛选;若你想找的是"一份可用于心律失常检测的老心电",路径是从心电类目进,再按年代筛选。两条路径都会落到这个库,但看的东西完全不同:前者看通道结构,后者看注释标签。
检索时值得用的关键词有三组:机构缩写(MGH、Marquette)、信号类型(hemodynamic、critical care waveform)、格式(WFDB、PhysioNet)。只用机构缩写容易漏掉同院其它资源,只用信号类型容易混入现代的监护数据库,三组一起用最准。
6.3 与库内心电词条的分工
库内心电词条大多以"心律分类"或"心电身份"为主题,本库与之的分工很清楚:前者回答"这一拍是什么",后者回答"这一拍发生的时候,血压和呼吸在做什么"。两者叠加使用,才构成一次完整的多参数观察。若研究对象是单导联的形态学,用专做心电的词条更直接;若研究对象是循环与呼吸的耦合,本库几乎不可替代(§4.4)。
§7 质量评估与局限性
7.0 阅读本节前的一个前置校正
在给这份库打分之前,要先校正一个常见的误判:把它当"数据集"来评,而不是当"存档"来评。数据集的评价标准是覆盖度、标注密度、可用性;存档的评价标准是保真度、可追溯性、上下文完整度。若用覆盖度去衡量一份 1990 年代的院内存档,结论必然是"人群太窄、通道太少、没有结局"——这些都对,但没有解释力。
把口径摆正之后,评价的落点就变成三件事:它保存下来的东西,今天还能不能找到第二份;它标注的东西,是不是当年的现场人员标的;它的缺陷,是设计取向还是疏漏。三个问题的答案,决定了它适合被当作什么用。
7.1 五维评分
若把数据交换标准(DAIMS)常被追问的几个维度——可发现、可访问、可互操作、可复用、可追溯——拿来当评分框架,本库的长短恰好分布得很清楚。
| 维度 | 评分 | 依据 |
|---|---|---|
| 可发现 | 高 | 有 DOI、有平台收录、有文献引用锚点 |
| 可访问 | 高 | 无需登录,整包可下,许可明确 |
| 可互操作 | 中 | 格式标准,但通道命名不统一、注释为自由文本 |
| 可复用 | 中高 | 许可宽松、工具链成熟,但需要大量清洗 |
| 可追溯 | 中 | 有采集机构与年份,无原始病历与设备型号 |
DAIMS 这套框架关心的正是"这份数据在交换与复用时会不会掉信息"。本库在可发现与可访问两项上接近满分,原因是它上线早、挂在了被广泛引用的平台上;在中后三项上则体现出典型的老库特征:格式已经标准化,内容却留在了当年的自由文本里。
7.1.1 五个维度里的两条短板
短板之一是可互操作。WFDB 本身是标准,但本库把语义留在了自由文本里:通道名有 ECG lead I、ECG I、ECG Lead I 三种大小写写法,压力通道有的写 ART 有的写 Pressure,注释段落标题的措辞也不统一。任何跨记录聚合都要先做归一化,否则同一路信号会被拆成三四个类别。
短板之二是可追溯。可追溯到机构与年份,却无法追溯到具体病历、具体设备型号、具体导管规格。头文件能告诉你这位患者做过右心导管,不能告诉你用了哪一根导管、测压传感器是外置还是内置。对波形形态研究影响有限,对器械研究则可能是关键缺口。
| 短板 | 具体表现 | 缓解办法 |
|---|---|---|
| 语义不统一 | 通道名大小写与措辞不一致 | 建索引时统一映射到八个代号 |
| 段落标题不统一 | 注释小节标题措辞随记录变化 | 用关键词而非精确标题匹配 |
| 无设备型号 | 头文件不记监护仪与传感器型号 | 在方法段写明库级不确定性 |
| 无导管规格 | 只记"置入导管",不记编号 | 用事件时间线做定性推断 |
| 无量化标定误差 | 只记标定发生过 | 优先分析相对变化 |
7.2 注释的真实覆盖范围
注释文件命名很朴素,ANNOTATORS 里只写了一个 ari,含义是心搏和事件。官方对它的说明也很克制:这些注释是为了帮助使用者定位记录中有意思的片段而提供的,编写过程认真,但仍可能含有少量错误。
这句话要读两遍。第一遍读出的是"有注释",第二遍读出的是"注释是为了定位片段,不是为了逐搏校验"。这意味着把它当逐搏真值使用时,需要有后备核对手段——比如用动脉压的重搏切迹反查心搏位置,或用多路信号投票。官方自己也承认错误可能存在,这正是它没把自己定位成基准库的原因。
7.3 已知的、可枚举的偏差
| 偏差 | 表现 | 影响 | 应对 |
|---|---|---|---|
| 时代偏差 | 采集于 1990 年代初 | 监护设备、导管、用药与今天不同 | 明确写成时代对照 |
| 中心偏差 | 单一医院 | 人群与操作习惯不代表其它机构 | 补充多中心数据 |
| 场景偏差 | 重症、手术、导管室三类 | 不代表门诊或居家 | 不用于院外推断 |
| 通道缺损 | 存在 No signal 占位 |
均值与相关性被拉偏 | 索引时标记并剔除 |
| 命名不一致 | Pressure、Pressure1/2 等笼统名 |
按位置索引会读错信号 | 强制按名索引 |
| 注释误差 | 官方承认可能有少量错误 | 逐搏真值不可直接采信 | 多信号交叉核对 |
| 采样上限 | 360 Hz | 高频成分不可分析 | 换库或降级分析目标 |
| 标定质量 | 无量化误差记录 | 绝对压力可能偏 | 优先用相对变化 |
八条偏差里,前三条属于采集设计的固有属性,改不了;后五条是使用层面的坑,可以在流程里处理掉。写作与建模时,最有价值的是把前三条写在方法段,把后五条写成清洗步骤。
7.4 外部验证矩阵
| 验证方式 | 是否可行 | 说明 |
|---|---|---|
| 与其它库对照人群构成 | 部分可行 | 只能比大致年龄段与病种关键词 |
| 与其它库对照波形形态 | 可行 | 心电形态在不同库间可比 |
| 重复测量检验 | 不可行 | 每患者仅一段,无重复 |
| 专家二次判读 | 可行 | 心电判读可重新做,成本可控 |
| 与器械台架对照 | 可行 | 压力轨迹可复现于测试台 |
| 与病历对照 | 不可行 | 无病历可回溯 |
第三行是这份库的结构性缺口。做测量一致性研究时,重复测量是常用手段;这里每位患者只有一段记录,无法在同一人身上做重复,只能在不同人之间做。第四行反而是它的优势——心电判读可以请现代医师重做一遍,与头文件里的原始判读对照,得到一份"三十年前后判读差异"的研究。
7.5 它为何能持续:一份没有替代品的老存档
公开库里做多参数重症波形的不多,做成这样"八路同轴、事件按分钟标注、能追溯到具体患者、还附一套回放软件"的更少。它的价值不在于样本量,而在于那些已经不会再被复现的采集场景:右心导管在位时肺动脉压与心电的同轴记录、气囊反搏运行时的压力形态、导管冲洗与置零在波形上留下的瞬时扰动。这些东西在任何新采集的数据库里都很难再凑齐,因为现代导管室与监护病房的操作流程、设备与记录方式都已改变。
它之所以能持续存在,靠的是三点:许可足够宽松,任何人可以下载并再分发;格式足够标准,WFDB 从 1990 年代用到现在,读取工具没有断代;上下文足够完整,头文件里那些看似啰嗦的事件行,让三十年后的使用者仍能还原当时发生了什么。
§8 生态位与历史
8.1 历史沿革:从仪表磁带到一个 DOI
这段历史可以按介质来分:磁带期、光盘期、网络期。磁带期是采集现场,八通道仪表磁带是唯一载体,回放与数字化靠专用设备。光盘期是分发期,十张 CD-ROM 里装着数字化后的数据、CAPE 软件、早期 WFDB 工具,以及一份从 MIT-BIH 心律失常库摘出来的示例片段。网络期从 2002 年开始,数据被挂到 PhysioNet 上,CD-ROM 里的 bin、lib、mitdb 三个目录没有随之上线,因为其中的工具早已被更好的版本取代。
三个阶段里,最容易被忽略的是光盘期。官方说明 CD-ROM 里除数据外还有一批 MS-DOS 时代的 WFDB 应用程序与库,这些程序今天已无用,但它们的存在说明这份数据从一开始就是"带工具发布"的——这在 1990 年代是相当超前的做法(§8.3)。
8.2 与后续研究的关系
从欧洲 PMC 检索可见,本库在近年的论文里出现的位置相当固定:要么作为多参数信号的真实性来源,要么作为波形生成模型的训练或评测数据。有把心电与动脉压、肺动脉压联合做心搏检测的隐马尔可夫模型工作,有把心电生成动脉压、中心静脉压、肺动脉压的深度自编码器工作,也有把库中正常与心律失常段拿来驱动体外循环仿真回路的研究。这些用法有一个共同点:都把它当"信号的真实样本",而不是"人群的统计样本"。
这条脉络解释了它的生态位。它不是用来回答"重症患者群体长什么样"的,而是用来回答"真实的重症波形长什么样"。前者需要大规模、多中心、带结局;后者只需要一段够真、够全、够同步的记录。
8.3 生态位:一个带说明书的标本盒
用一句话定位:它是标本盒,不是标本库。盒子里二百五十份标本,每份都附一张手写标签——这位是谁、多少岁、当时在做什么、哪一分钟插了导管。标本本身不可复制,标签则是它最值钱的部分。
这个定位带来一个实用推论:使用者应当优先读标签,再读波形。头文件里的那十几行注释,往往比波形本身更能决定这段记录值不值得用。想找起搏心律,注释里写了"永久性起搏器";想找气囊反搏,注释里会提;想找导管操作,事件时间线按分钟列好。先读标签再取数,能省掉大量试错。
再补一层:标本盒的价值随时间上升,而不是下降。新采集的数据每年都在增加,九十年代初的磁带录音不会再增加。当研究问题转向"多参数波形在三四十年前长什么样""当年的导管操作在压力曲线上留下什么痕迹"时,可选范围只会缩小。这种稀缺性是它至今仍被引用的结构性原因,与样本量无关。
8.4 谁在用它,用来做什么
| 使用者类型 | 典型用途 | 需要额外准备 |
|---|---|---|
| 信号处理研究者 | 心搏检测、波形重建、去噪 | 自建切分与清洗流程 |
| 器械与仿真工程师 | 压力轨迹作为测试台边界条件 | 挑选典型段并做幅值缩放 |
| 教学人员 | 演示监护仪输出与临床事件的对应 | 准备事件时间线的讲解材料 |
| 数据平台建设者 | 作为 WFDB 格式的样例数据 | 无,工具链现成 |
| 方法学论文作者 | 作为"真实多参数信号"的对照 | 明确写出年代限制 |
五类使用者里,第四类最容易上手,因为他要做的事恰好是这个库最擅长的:把数据读进来、画出来、验一遍格式是否一致。第一类最辛苦,因为清洗工作量大。第三类最受益,因为事件时间线本身就是现成的教案。
§9 使用指引
9.1 三种角色的路径
| 角色 | 起点 | 第一个产出 | 常见卡点 |
|---|---|---|---|
| 算法工程师 | 先读 §2.2 的字段字典与 §5.3 的索引脚本 | 一份带通道归一化的索引表 | 忽略 No signal 与笼统通道名 |
| 临床研究者 | 先读目标记录的头文件注释 | 一段可复述的临床背景 | 把注释误当结构化诊断 |
| 教学与平台人员 | 先跑 §5.2 的单记录读取 | 一张八路并排的总览图 | 以为 360 Hz 是整数巧合 |
三个角色的路径差异很大,唯一共同的第一步是"先读头文件"。这一点在别的库上未必成立——很多库的结构化字段表足够完整,跳过注释也能干活;在这个库上不行,因为一半以上的关键信息在注释里。
9.2 一条最短的可用流程
从零到能画出一张八路总览图,只需要四步。
#-- 第一步:取一条记录的头文件与注释,先看结构
curl -s https://physionet.org/files/mghdb/1.0.0/mgh001.hea
#-- 第二步:装好 WFDB 工具(Python 版即可)
pip install wfdb numpy matplotlib
import wfdb
import numpy as np
import matplotlib.pyplot as plt
rec = wfdb.rdrecord("mgh001", pn_dir="mghdb/1.0.0")
ann = wfdb.rdann("mgh001", "ari", pn_dir="mghdb/1.0.0")
fs = rec.fs
start = int(20 * fs)
seg = rec.p_signal[start:start + 10 * fs, :]
fig, axes = plt.subplots(8, 1, figsize=(10, 10), sharex=True)
t = np.arange(seg.shape[0]) / fs
for k, ax in enumerate(axes):
ax.plot(t, seg[:, k], lw=0.6)
ax.set_ylabel(rec.sig_name[k], fontsize=7)
axes[-1].set_xlabel("seconds")
fig.tight_layout()
fig.savefig("mgh001_8ch.png", dpi=150)
三个变量值得留意。rec.sig_name 是通道名列表,正是 §6.2 里说"最该保留"的那一列;start 取第二十秒,是为了跳过记录开头常见的标定脉冲;sharex=True 保证八路共用一条时间轴,这与 §3.3 说的"通道间无回放错位"相呼应。§4.2 的案例用同一套代码即可复现它的三层信息。
第四步是核对:把图上可见的心搏位置与注释里的样本位置对齐,若偏差超过几个样本,说明通道选错了或者过滤出了问题。
9.3 引用方式
| 字段 | 内容 | 用途 |
|---|---|---|
| 数据集 | Welch JP, Ford PJ, Teplick RS, Rubsamen RM. The Massachusetts General Hospital-Marquette Foundation Hemodynamic and Electrocardiographic Database — Comprehensive collection of critical care waveforms. J Clinical Monitoring 7(1):96-97 (1991) | 原始文献,官方指定的引用对象 |
| 平台 | Pollard T 等,PhysioNet as a global platform for biomedical research | 平台引用 |
| 版本 | MGH/MF Waveform Database v1.0.0 | 精确定位 |
| 标识 | DOI 10.13026/C26K5Q | 可解析链接 |
| 许可 | ODC-BY 1.0 | 署名要求 |
官方在这份库上没有单独的数据集论文,只在 PhysioNet 页面上给出上面那篇 1991 年的介绍文章作为"使用本资源时应引用的原始出版物"。所以引用时基本就是两行:一行致敬原始文献,一行写平台、版本与 DOI。三点需要注意:版本号自 2002 年以来一直是 1.0.0,但 2017 年做过内容修订,写清下载日期更稳妥;DOI 指向 v1.0.0,带 DOI 的引用已隐含版本;许可要求署名,商用同样需要。
9.4 复现一份最小报告的四步检查
| 检查点 | 预期 | 不符时的常见原因 | 处理 |
|---|---|---|---|
| 通道数 | 8 | 头文件被截断或读到的是别的库 | 用 rdheader 重新读 |
| 采样率 | 360 | 手写了 250 或 500 | 一律从 fh.fs 取 |
| 注释记录 | 心搏为主,事件为辅 | 未按标签字符过滤 | 先过滤再算 RR |
| 日期字段 | 日/月/年 | 按美式日期解析 | 显式指定 dayfirst |
第三步之所以排在日期之前强调,是因为它对下游影响最大。RR 间期一旦混入事件记录的位置差,得到的序列里会出现若干毫秒级的"心搏",任何心率变异性分析都会被这些假间期带偏。过滤逻辑很简单:只保留标签字符属于心搏集合的记录,其余丢弃并单独存档,供事件对齐使用。
9.5 三类人群的最短路径
只想要一张图。 装 WFDB,读一条记录,取一段三十秒,八路并排画出来,二十分钟内能完成。这条路径不需要建索引,也不需要处理缺损通道,适合第一次接触这份数据的人建立直觉。
要一份可训练的张量。 先跑附录 D 的索引脚本,把 250 条记录分成通道齐全与缺损两池;再按记录号切分训练、验证、测试;最后按 §5.4 的窗函数切片并逐通道标准化。这条路径的关键是"按记录切分",不是"按窗切分"。
要一份跨库对照实验。 先确定对照的问题是什么——是人群、是波形形态、还是采集年代。若是年代,本库提供的是九十年代初的一段切片;若是波形形态,只需挑几类有代表性的记录。切忌把整库灌进现代模型再声明"外部验证",那会把时代差异与领域差异混在一起。
| 路径 | 最少步骤 | 主要风险 |
|---|---|---|
| 只看图 | 读一条记录,画八路 | 选错时间窗,落在标定段 |
| 建张量 | 索引、分层、切窗、标准化 | 按窗随机切分导致泄漏 |
| 跨库对照 | 定问题、挑记录、写清差异 | 把时代差异读成模型退化 |
9.6 复现性清单:别人能不能照你的描述重建
一篇用到本库的论文,若想让别人照着重跑,需要的不是更多数字,而是把"怎么从 250 条里挑出你用的那几条"写清楚。下表按可操作性排列。
| 必写项 | 为什么必须写 | 常见缺漏 |
|---|---|---|
| 使用的记录名 | 库内流水号本身不表意 | 只写"选取若干条" |
| 通道名与归一化方式 | 同一路写法不统一 | 只说"心电与血压" |
| 是否剔除缺损通道 | 影响样本量与均值 | 不作说明 |
| 切窗长度与步长 | 直接决定样本数与泄漏风险 | 只给窗长不给步长 |
| 切分单位 | 按记录切与按窗切结论不同 | 只写"随机划分" |
| 注释过滤规则 | 事件记录混入会污染 RR | 未交代 |
| 采集年代的处理 | 时代差异是结论的一部分 | 混入"外部验证" |
| 下载日期 | 2017 年修订过内容 | 只写版本号 |
八项里最容易被忽略的是最后一项。版本号自 2002 年以来没变过,但 2017 年修正过五个头文件的长度并截断了一个数据体。若审稿人用的是修订前的镜像,同一条记录读出来长度不同,切窗结果自然不同。写清下载日期,成本极低,收益很大。
§10 AI 使用声明
| 项目 | 内容 |
|---|---|
| 写作方式 | 由人工智能辅助撰写,人工校核事实与表述 |
| 事实来源 | 官方项目页、RECORDS 清单、ANNOTATORS 声明、头文件与注释文件、欧洲 PMC 检索结果 |
| 未使用的手段 | 未下载全量数据做分布统计,未做频次、空值率或逐条样本明细分析 |
| 数字口径 | 官方页面与头文件给出什么就写什么,不推断不补全 |
| 不确定项处理 | 标注"官方未公布"或"工作假设",不写成事实 |
| 表格中的预期值 | 明确标注为几何推断或工作描述,与官方结论分开 |
| 封面图 | 由生成模型按风格提示词产出,不含真实数据 |
| 更新责任 | 若官方页面修订,以官方为准,本页随之更新 |
常见误读(避坑清单)
| 说法 | 实际 | 证据 |
|---|---|---|
| MGH 是某个模型或指标缩写 | 是 Massachusetts General Hospital 的机构缩写 | 官方标题展开 |
| MF 是文件格式 | 是 Marquette Foundation 的基金会缩写 | 官方标题与引用文献 |
| 这是一份十二导联心电库 | 只有三路心电,另五路为压力与呼吸信号 | 头文件通道行 |
| 每条记录都是八路满信号 | 存在 No signal 占位通道 |
mgh050、mgh250 头文件 |
| 采样率是 500 Hz 或 1000 Hz | 每秒 360 样本 | 头文件第一行 |
| 注释是逐搏金标准 | 官方称其为定位片段之用,可能含少量错误 | 官方数据描述 |
| 记录时长统一为一小时 | 十余分钟至八十余分钟,多数约一小时 | 官方数据描述 |
| 是现代重症患者的代表样本 | 1990 年代初单中心 250 人 | 引用文献年份与头文件时间戳 |
| 有结局与用药记录 | 只有波形、注释与一句诊断 | 目录结构 |
| 整库不到一吉字节 | 未压缩约 4.2 GB | 官方文件列表 |
FAQ
问:MGH 到底指什么?
答:Massachusetts General Hospital,即麻省总医院。它不是"Mass General Hospital"的随意缩写,也不是某个算法或指标的代号。与之并列的 MF 指 Marquette Foundation,两家机构合作产出了这份库,官方全名把两个缩写用斜杠连在一起(§1.2)。
问:它和公开的心电数据库有什么根本不同?
答:多数公开心电库只存心电,本库存的是床旁监护仪同时打出的八路波形,心电只占三路。它更接近一台监护仪的输出切片,而不是一份心电图归档。也因此,它的注释里除了心搏还有导管与标定事件。
问:八路信号具体是哪八路?
答:典型记录是心电 I、心电 II、心电 V、动脉压、肺动脉压、中心静脉压、呼吸阻抗、气道二氧化碳。部分记录把后几路换成颅内压、左房压、心室压或主动脉内球囊压,也有记录出现 No signal 占位(§2.4)。
问:记录里的注释能直接训练心搏检测器吗?
答:可以研究,但要先做两件事。一是按标签字符把标定、置零、冲管这类事件记录滤掉,只留心搏记录;二是抽查心搏位置是否落在 QRS 上,因为官方明确说注释可能含少量错误(§7.2)。
问:为什么每条记录长度不一样?
答:它们本来就是一段连续的床旁监护,起止由当时的操作决定,不按固定时长裁剪。官方说明在十余分钟到八十余分钟之间,多数约一小时。使用时按固定窗长切分,需要处理末尾剩余。
问:采样率为什么是 360 Hz 这个数?
答:因为原始采样是每秒 1440 个样本,回放时按二倍抽取,得到每秒 360 个样本。这个数字不是为心电分析挑的最优值,而是两倍速回放加二倍抽取的直接结果(§3.3)。
问:能否直接用于现代临床模型训练?
答:不建议单独使用。记录来自 1990 年代初的单中心监护人群,没有结局变量,通道有效性也不齐。把它当代时代对照或外部验证集合适,当主训练集则容易把当年的监护习惯与设备特性学进去。
问:为什么不给出总时长?
答:官方只说明单条时长范围与整库体积,没有给出总小时数。要得到总时长须逐条读取 250 个头文件相加,那属于统计工作,不在本页范围内(§4.5 讨论过它不给出的人群分布)。
问:有性别、年龄这些人口学信息吗?
答:多数记录的头文件注释里有年龄与性别,格式是尖括号包裹的字段名加数值。但不是每条都有,也没有结构化字段表。做分层分析前要先把缺失记录下来。
问:这套数据有配套软件吗?
答:有,cape 目录里有 CAPE 患者模拟器的演示版本与文档,可以把存的波形按实时速度回放。含 ISA 总线板卡的完整版需向 Cardionics 索取。今天多数人用不到它,但它是这个库"带工具发布"传统的证据(§8.1)。
问:和现代的重症波形数据库怎么选?
答:看问题。要结局、要人群、要现代设备,用现代库;要真实的多参数同步波形、要能逐分钟对上临床操作,用这份。两者不是替代关系,跨时代并置时写"时代对照"更准确(§3.5)。
问:头文件第一行的日期该怎么读?
答:日/月/年。例如 mgh175 写作 05/09/1991,指 1991 年 9 月 5 日,不是 5 月 9 日。格式是欧洲写法,跨库合并时间轴时若用默认的美式解析,整条记录会差出四个月(§2.1)。
问:为什么很多记录没有起止日期?
答:采集与数字化是分批完成的,头文件里的日期字段并非每条都填。缺日期的记录只能靠流水号与内容推断大致顺序,不能当精确时间使用。这一点在做时代分层时必须承认。
术语表
| 术语 | 英文 | 在本库中的含义 |
|---|---|---|
| 波形数据库 | waveform database | 以连续生理信号为主体的数据库 |
| 血流动力学 | hemodynamic | 血压、心输出等循环相关参数的统称 |
| 动脉压 | arterial pressure, ART | 动脉置管测得的压力波形 |
| 肺动脉压 | pulmonary arterial pressure, PAP | 右心导管测得,反映肺循环压力 |
| 中心静脉压 | central venous pressure, CVP | 上腔或下腔静脉近心端压力 |
| 呼吸阻抗 | respiratory impedance | 胸廓阻抗随呼吸的变化,用作呼吸相位参考 |
| 气道二氧化碳 | airway CO2 | 呼吸回路中二氧化碳浓度波形 |
| 颅内压 | intracranial pressure, ICP | 部分记录中的脑室内或实质压力 |
| 左房压 | left atrial pressure, LAP | 部分记录中经房间隔穿刺测得 |
| 气囊反搏 | intra-aortic balloon pump, IABP | 主动脉内球囊反搏的压力通道 |
| 楔压 | wedge pressure, PCW | 肺动脉楔入压,反映左房充盈压 |
| 炮波 | cannon wave | 房室不同步时中心静脉压上的异常 a 波 |
| 标定脉冲 | calibration pulse | 记录开头用于换算物理量的方波 |
| 压力置零 | zero pressure | 把当前压力当作参考零点的操作 |
| 记录 | record | 一名受试者一段监护的完整信号单位 |
| 头文件 | header file | WFDB 文本描述文件,后缀 hea |
| 数据体 | data file | WFDB 二进制文件,后缀 dat |
| 注释文件 | annotation file | 心搏与事件标签,后缀 ari |
| 注释器 | annotator | 注释的类型声明,本库仅 ari |
| 抽取 | decimation | 降低采样率,本库为二倍 |
| 抗混叠 | anti-aliasing | 抽取前压制带外成分的滤波 |
| 相位失真 | phase distortion | 滤波引起的不同频率成分相移 |
| 采样率 | sampling rate | 每秒样本数,本库 360 |
| 量化解位 | bit depth | 有效位数,本库 12 位存于 16 位 |
| 物理量换算 | physical conversion | 按增益与基线把数字换算成毫伏或毫米汞柱 |
| 占位通道 | placeholder channel | 描述为 No signal 的有效性为零通道 |
| 主键 | primary key | 记录名,全库唯一 |
| 日/月/年 | DD/MM/YYYY | 头文件日期格式,非美式 |
| 时代偏差 | era bias | 采集年代与当代临床实践不同带来的偏差 |
| 开放许可 | ODC-BY 1.0 | 允许包括商用在内的使用,需署名 |
附录 A:核心数字核对表
| 项 | 值 | 来源 | 来源层级 |
|---|---|---|---|
| 患者数 | 250 | 官方摘要与 RECORDS | 官方 |
| 记录数 | 250 | RECORDS 逐行 | 官方 |
| 每记录通道数 | 8 | 头文件第一行 | 官方 |
| 采样率 | 每秒 360 样本 | 头文件第一行 | 官方 |
| 原始采样率 | 每秒 1440 样本 | 官方数据描述 | 官方 |
| 量化解位 | 12 位 | 通道行格式码 212 | 官方 |
| 单条时长范围 | 十余分钟至八十余分钟 | 官方数据描述 | 官方 |
| 常规心电路数 | 3 | 头文件通道行 | 官方 |
| 常规压力与气流路数 | 5 | 头文件通道行 | 官方 |
| 整包体积 | 未压缩约 4.2 GB | 官方页面 | 官方 |
| 版本 | 1.0.0 | 官方页面 | 官方 |
| 发布日期 | 2002-06-10 | 官方页面 | 官方 |
| 最近内容修订 | 2017-01-03 | 官方更新说明 | 官方 |
| 许可 | ODC-BY 1.0 | 官方页面 | 官方 |
| DOI | 10.13026/C26K5Q | 官方页面 | 官方 |
| 引用文献年份 | 1991 | 官方引用 | 官方 |
| 每秒样本数(换算) | 21600 | 360 乘 60 | 推导 |
| 示例记录 | mgh001 约 63.7 分钟 | 样本数除以采样率 | 推导 |
| 示例记录 | mgh210 约 82.7 分钟 | 样本数除以采样率 | 推导 |
附录 B:数字的来源分层
| 层级 | 含义 | 本页涉及的数字 |
|---|---|---|
| 官方页面 | PhysioNet 项目页与其文件列表直接给出 | 患者数、通道数、采样率、时长范围、体积、版本、日期、许可、DOI |
| 官方文件 | 头文件、RECORDS、ANNOTATORS 的内容 | 样本总数、通道名、增益与基线、年龄性别诊断、事件时间线 |
| 论文摘要 | 欧洲 PMC 检索到的相关研究 | 库在文献中的典型用途,不作规模数字来源 |
| 推导 | 由官方数字直接换算 | 每秒 21600 样本、单条时长换算、每秒约 5.8 KB 的体积估算 |
| 工作假设 | 依据注释提出、官方未验证 | 导管室记录的通道归属推断、Pressure 序列的节段猜测 |
前两层可直接引用;第三层只用于说明生态位;第四层可复算,写论文时若要引用应自行计算;第五层必须写明是推断。
附录 C:完整参考文献
| 序号 | 文献 | 用途 |
|---|---|---|
| 1 | Welch JP, Ford PJ, Teplick RS, Rubsamen RM. The Massachusetts General Hospital-Marquette Foundation Hemodynamic and Electrocardiographic Database — Comprehensive collection of critical care waveforms. J Clinical Monitoring 7(1):96-97, 1991. | 官方指定的原始文献 |
| 2 | PhysioNet. MGH/MF Waveform Database v1.0.0. 2002-06-10. DOI 10.13026/C26K5Q. | 官方数据页 |
| 3 | Pollard T, Moody BE, Lehman L, Gow B, Fernandes C, Xie C, Johnson A, Mark RG, Heldt T. PhysioNet as a global platform for biomedical research. Nature Health, 2026. | 平台引用 |
| 4 | Goldberger A, et al. PhysioBank, PhysioToolkit, and PhysioNet. Circulation, 2000. | WFDB 与平台背景 |
| 5 | Open Data Commons. Attribution License v1.0. | 许可文本 |
| 6 | 欧洲 PMC 检索结果(主题词 MGH/MF),含多参数心搏检测、波形生成与器械仿真类研究 | 生态位说明 |
附录 D:任务代码
一段把全库读成索引、再按通道可用性分池的完整脚本。
import re
from pathlib import Path
CODES = {
"ECG": "ecg", "ART": "art", "PAP": "pap", "CVP": "cvp",
"RESP": "imp", "CO2": "co2", "ICP": "icp", "PRESSURE": "prs",
}
def normalize(name):
key = name.upper().replace(".", " ").strip()
for k, v in CODES.items():
if k in key:
return v
if key in ("NO SIGNAL", "NO SIGNAL "):
return "none"
return "other"
def read_one(path):
lines = Path(path).read_text(encoding="utf-8", errors="replace").splitlines()
h = lines[0].split()
nch = int(h[1])
chans = []
for l in lines[1:1 + nch]:
parts = l.split()
chan = " ".join(parts[8:]) if len(parts) > 8 else ""
chans.append(normalize(chan))
body = "\n".join(lines[1 + nch:])
age = re.search(r"<age>:\s*(\d+)", body)
sex = re.search(r"<sex>:\s*([MF])", body)
return {
"name": h[0],
"n": int(h[3]),
"chans": chans,
"valid": sum(1 for c in chans if c not in ("none", "other")),
"age": int(age.group(1)) if age else None,
"sex": sex.group(1) if sex else None,
}
rows = [read_one(p) for p in sorted(Path("mghdb").glob("mgh*.hea"))]
full = [r for r in rows if r["valid"] == 8]
partial = [r for r in rows if 0 < r["valid"] < 8]
empty = [r for r in rows if r["valid"] == 0]
print(len(rows), len(full), len(partial), len(empty))
脚本里有两点是刻意的。第一,normalize 在匹配不到已知代号时返回 other 而不是报错,因为 No signal 与 Pressure 这类名字在头文件里大小写与空格都不统一,硬匹配会漏。第二,read_one 用 len(parts) > 8 判断通道描述是否存在,因为有些记录的通道描述为空,直接取最后一个字段会把增益值当成名字。
跑完之后,full、partial、empty 三个列表就是后续分层评测的基础。§5.5 的评测协议里说的"按通道完整性分两池",具体到代码就是这个划分。
附录 E:如果只记五件事
| 序号 | 要点 |
|---|---|
| 一 | MGH 是麻省总医院,MF 是 Marquette Foundation,两个机构缩写拼成的库名 |
| 二 | 250 名患者,每人 8 路同步波形,心电只占 3 路,其余是压力、呼吸与气体 |
| 三 | 每秒 360 样本,来自 1440 采样二倍抽取,别指望高频心电分析 |
| 四 | 注释含心搏与事件两类,官方承认可能有少量错误,用作定位而非逐搏真值 |
| 五 | 1990 年代初单中心存档,适合做真实多参数信号与时代对照,不适合做人群推断 |
编辑说明
本页按 v4 编辑纪律撰写:只写规模、结构、边界三类数字,不做分布统计与逐条样本明细;官方自相矛盾处并列两口径,不下判断。页面中的时长换算、体积估算与通道归一化均标注为推导,与官方表述分开。若 PhysioNet 页面后续修订版本号或更新文件列表,以官方为准,本页随之更新。
相关数据集导航
以下为站内 AI-Ready 数据集百科中与本词条共享多个主题标签的相关数据集,按相关度降序排列:
- pulsedb — 共享标签:生理信号 / 心电信号 / 电子健康记录 / 重症监护
- barcelona-sicu-signals — 共享标签:生理信号 / 电子健康记录 / 重症监护
- tpehgdb — 共享标签:生理信号 / 心电信号 / 电子健康记录
- cinc-2015 — 共享标签:生理信号 / 心电信号 / 电子健康记录 / 重症监护
- mover — 共享标签:生理信号 / 心电信号 / 电子健康记录 / 重症监护
- mimic-iv-ext-ecg-glucose — 共享标签:生理信号 / 心电信号 / 电子健康记录 / 重症监护
- ob1db — 共享标签:生理信号 / 心电信号 / 电子健康记录
- sicdb — 共享标签:生理信号 / 电子健康记录 / 重症监护
- mc-med — 共享标签:生理信号 / 电子健康记录 / 重症监护
- vtac — 共享标签:生理信号 / 心电信号 / 重症监护
导航说明:本章节由全站统一标签体系自动计算生成(标签重合度算法),双向可达;点击链接可跳转至对应数据集词条。

