信息速览
ST 段压低一百微伏,算不算一次缺血事件?这个问题在动态心电分析里有三十多年的争议,而争议的核心从来不是临床判断,而是「没有一把公认的尺子」。心律失常领域很早就解决了这件事:MIT-BIH 心律失常库与 AHA 室性心律失常库先后成为公共基准,任何人写的 QRS 检测器都能在同一套数据上被量化打分。心肌缺血这边却一直缺位——Holter 厂商各自宣称自己的 ST 分析敏感度百分之九十几,彼此之间没有一个共享的答案。
European ST-T Database 就是为填补这个空缺而生的。它不是一个「更多数据」的心电库,而是一套约定:什么算一次 ST 事件、什么时候算开始、峰值怎么测、偏差相对于谁。九十段两小时的双通道动态心电记录(下文统一称心电),每段都附上两位心脏病专家各自独立做的标注,分歧由设在比萨的协调组裁决。它的价值在于可比较性——论文里的算法只要在同一批记录上跑一遍,就能和 1992 年以来的公开结果放在同一张表上。
但它的门槛也恰恰在这套约定里。这套库注释的不是「ST 电平」的绝对值,而是相对于每段头三十秒参考波形的偏移量。把注释当成「此处 ST 抬高 0.2 毫伏」直接喂给模型,从第一步就走错了。同时它的导联组合逐记录浮动、官方点名的七组记录来自同一批受试者、许可证是 ODC-BY 而非常见的 CC-BY,这些细节共同决定了它能被怎么用。一屏速览见下表。
| 维度 | 内容 |
|---|---|
| 全名 | European ST-T Database |
| 发布方 | PhysioNet;原始数据由欧洲心脏病学会支持的欧洲共同体「动态心电监护协同行动」产出,比萨 CNR 临床生理研究所与鹿特丹 Erasmus 大学胸科中心主持完成 |
| 首次发布 | 2000 年 9 月 30 日上线近半;2009 年 11 月 27 日全量上线,版本 1.0.0 |
| 最近改动 | 2019 年 2 月 20 日更新 SHA256SUMS.txt;记录本体文件时间统一为 1991 年 5 月 10 日 |
| 记录数 | 90 段 |
| 受试者数 | 79 名(70 男 30–84 岁,8 女 55–71 岁,1 名信息缺失) |
| 每段时长 | 2 小时(1,800,000 采样点) |
| 通道数 | 2(导联组合逐记录不同,常见 V4、V5、V2、V1 配 MLIII 或 MLI) |
| 采样率与分辨率 | 250 Hz,12 位分辨率,标称 20 毫伏输入范围,统一标定为 200 ADC 单位/毫伏 |
| 每段信号文件体积 | 5,400,000 字节(12 位打包存放) |
| 总体积 | 465.1 MB(未压缩) |
| 原始来源 | 79 名受试者的动态心电 Holter 记录节选 |
| 标注规模 | 参考注释文件合计 802,866 条;其中含 367 段 ST 事件与 401 段 T 波事件 |
| 标注生成方式 | 斜率敏感的 QRS 检测器出初标 → 两位心脏病专家各自独立全文核对并修正 → 比萨协调组裁决分歧 |
| 文件格式 | WFDB:.hea 头文件 / .dat 信号 / .atr 注释,另附 ANNOTATORS、RECORDS、edb.txt、annotations.shtml、thanks.shtml、SHA256SUMS.txt |
| 许可 | Open Data Commons Attribution License v1.0(ODC-BY 1.0),无需注册即可下载 |
| 标识符 | DOI 10.13026/C2D59Z |
| 典型用途 | ST/T 分析算法的性能评测、AAMI EC38 与 EC57 类标准符合性测试、缺血检测器的开发与溯源比较 |
§1 它要解决的具体麻烦
1.1 心律失常有标准答案,缺血没有
心电图自动化评测的历史有一个清晰的分叉。节律类任务在上世纪八十年代就被标准化:一批公共记录带上逐搏标注,任何实验室的检测器都能在同一份数据上数出漏检与误检,数字可以直接横向比较。缺血类任务长期没有对应物,原因是它的判读对象不是一个离散事件,而是一条随时间缓慢漂移的曲线幅度。要给它做标准答案,必须先统一三件有了巨大自由度的事:测量点在 J 点之后多少毫秒、持续多久算一个事件、以及——最要命的——偏差是相对于谁。
European ST-T Database 的贡献正是把这三条写死并公开执行:测量点固定在 J 点之后 80 毫秒(心率超过 120 次/分时改为 60 毫秒);事件必须包含至少 30 秒的偏移区间;偏差相对于每段头三十秒里取出的参考波形。这三条写进 annotations.shtml,也写进 1992 年那篇 European Heart Journal。有了它,「某某算法的 ST 检测敏感度」第一次有了可对账的口径。
1.2 三条常见的错误期待
第一条,期待它是十二导联库。 它是双通道库,绝大多数记录是两个改良肢体导联或胸导联的组合。§2.6 会展开讲,导联组合逐记录浮动,看不见 V6 也看不见 aVF。
第二条,期待注释给出「此处 ST 抬高 0.2 毫伏」这样的绝对值。 它给的是相对偏移:相对该段头三十秒参考波形的变化量。有陈旧心梗、固定抬高的受试者,其「绝对电平」与「偏移」是两条不同的曲线,注释只记录后者。
第三条,期待每条记录来自不同受试者。 官方明确列出七组同源记录,最多的一组五段同属一人。按记录随机划分数据集会把同一个人的两次片段拆到训练与测试两侧,这是能被量化出来的泄漏路径。
1.3 它能给到的与给不到的
| 你的需求 | 它给的 | 够不够 |
|---|---|---|
| ST/T 分析算法的性能评测 | 统一判据下的事件起止与峰值,双通道独立标注 | 够,这是它被建出来的原因 |
| 训练一个缺血检测器 | 367 段 ST 事件、401 段 T 波事件 | 勉强,事件量级小,适合做监督信号而非大规模训练 |
| 长时程(24 小时级)缺血负荷研究 | 每段仅两小时 | 不够,需要长时程库补足 |
| 十二导联形态学研究(心梗定位、束支阻滞分型) | 每记录仅两路信号 | 不够,导联维度缺失 |
| 严格的心律失常分类基准 | 有逐搏标注,但设计与取舍都围绕 ST-T | 不够,应优先用心律失常专用库 |
| 跨算法的可比性评测 | 1992 年以来公开文献沿用同一批记录 | 够,且这是别的库替代不了的位置 |
| 人群代表性建模 | 79 人,男性占绝大多数,全部为确诊或疑似心肌缺血 | 不够 |
| 药物或干预疗效研究 | 头文件里有 medication 行,但无剂量、无时序、无结局 | 不够 |
1.4 你的处境与它能帮到的事
| 你的处境 | 它能帮你什么 | 下一步该做什么 |
|---|---|---|
| 你写了一个 ST 段测量算法,想证明它准确 | 同一判据下的参考事件,可直接做事件级与搭接级比较 | 先读 annotations.shtml 的判据,再按它的口径实现自己的偏差函数,最后用思路对齐的方式比对 |
| 你在做 Holter 分析系统的标准符合性测试 | 官方把 ANSI-AAMI EC38 与 EC57 列为参考标准 | 以 §5.5 的表格解析出事件三元组,按标准要求的指标算矛盾率与漏报 |
| 你要复现某篇论文里的 ST 分析成绩 | 记录名在文献里通常直接出现,可逐条对应 | 注意版本只有 1.0.0,且 2000 年之前只有注释文件可用,早期复现可能只用了部分记录 |
| 你在找「能否用于训练」的缺血数据 | 提供事件级监督,但规模有限 | 把它当作外部测试集,训练另找大库 |
| 你在教动态心电判读 | 双通道两小时,事件密度适中,附完整临床摘要 | 取 e0105 这类官方样例反复讲一次完整事件的三个注释点 |
| 你要做多中心泛化研究 | 记录来自八个国家的十三个研究组 | 记录名前缀(e01xx、e02xx … e13xx)可作为组级分组的线索,但官方未说明其含义,不宜当作正式变量 |
1.5 一句话判断
它不是训练集,而是一把刻度公开、被沿用了三十余年的尺子;用它「训练」是浪费,用它「量别人」才是正路,而用错它的最常见方式是把相对偏移当成了绝对电平。
1.6 不适合谁:四条边界
不适合拿来做规模训练。 九十段记录、三百六十七段 ST 事件,这个量级支撑不起端到端深度模型的参数量,结构上属于评测资产。
不适合拿来代表女性。 官方给出的性别构成是七十名男性与八名女性,另一名信息缺失。任何按性别分层的结论在这里都没有统计基础。
不适合拿来做日间变异研究。 每段固定两小时,且取自原始 Holter 的节选而非全程,无法回答「一天之内发作几次」这类问题。
不适合替代独立的本地验证。 原始记录来自八个国家的多个研究组、多种型号记录仪,异质性很高;这是优点也是缺点,用它算出的成绩不能直接当作在某一目标人群上的表现。
§2 数据构成与规格
2.1 一段记录由三个文件组成
它采用 WFDB(Waveform Database)格式,这是 PhysioNet 自八十年代沿用至今的物理信号存储规范。每一段记录对应同名的三个文件:
| 文件 | 类型 | 角色 | 缺了会怎样 |
|---|---|---|---|
e0103.hea |
纯文本 | 头文件:声明通道数、采样率、采样点数、格式、增益、位分辨率、ADC 零值、初始值、校验和、导联名,并以注释行给出年龄、性别、诊断、用药与记录仪型号 | 无法还原毫伏值,也无法知道哪一路是 V4 |
e0103.dat |
二进制 | 信号本体:两路 12 位采样交错存放 | 整个记录失去意义 |
e0103.atr |
二进制 | 参考注释:心搏、节律、ST/T 变化、信号质量 | 没有监督信号,退回无标注波形 |
后缀组合是恒定的:官方文件目录里 90 条记录每一条都同时具备 .hea、.dat、.atr 三个文件,没有缺项。这一点值得强调,因为官方页面本身提到过历史分两次上线——2000 年只贡献了 48 条完整记录,但全部 90 条记录的参考注释文件当时就已上线。最终版本补齐后,三者齐备。
根目录另有六个附属文件:
| 文件 | 大小/时间 | 内容 |
|---|---|---|
RECORDS |
540 字节,2000-09-29 | 全部 90 条记录名,每行一个 |
ANNOTATORS |
72 字节,2000-10-13 | 一行:atr reference beat, rhythm, ST/T change, and signal quality annotations |
edb.txt |
1999-10-12 | CD-ROM 说明原始文本,含整个欧洲 ST-T 段行动的背景、VALE 库介绍与参考文献 |
annotations.shtml |
2019 年以前一次更新(显示为 2015-08-19) | 标注流程与判据的完整文档,含 ST/T 事件定义规则与注释类型码表 |
thanks.shtml |
2015-08-19 | 致谢与贡献机构名单 |
SHA256SUMS.txt |
20,633 字节,2019-02-20 | 全部文件的 SHA256 校验和 |
目录里的文件总数为 276 个:90 条记录各三个文件(270),加上述六个附属文件。
2.2 头文件字段字典
它的「字段」不是表格列,而是 WFDB 头文件的关键字行与注释行。下表逐行给出 e0103.hea 这类文件的结构含义。
| 位置 | 取值形态 | 含义 | 使用注意 |
|---|---|---|---|
| 第 1 行第 1 字段 | e0103 |
记录名 | 与文件名同前缀 |
| 第 1 行第 2 字段 | 2 |
通道数 | 全部记录均为 2 |
| 第 1 行第 3 字段 | 250 |
采样率(Hz) | 统一 250,无例外 |
| 第 1 行第 4 字段 | 1800000 |
采样点数 | 除以采样率正好 7200 秒 |
| 信号行第 1 字段 | e0103.dat |
信号文件名 | 两通道共用同一个 .dat |
| 信号行第 2 字段 | 212 |
存储格式代码 | 两个 12 位样本打包成 3 字节,不可按 16 位直接读 |
| 信号行第 3 字段 | 200 |
增益,ADC 单位/毫伏 | 全库统一值,源自模数转换后按原始标定信号重新缩放 |
| 信号行第 4 字段 | 12 |
位分辨率 | 有效位数 12 |
| 信号行第 5 字段 | 0 |
ADC 零值 | 零电平对应的整数 |
| 信号行第 6 字段 | 如 91 |
首采样点整数值 | 用于流读取时还原差分链 |
| 信号行第 7 字段 | 如 56457 |
校验和 | 用于 .dat 完整性校验 |
| 信号行第 8 字段 | 0 |
每帧字节数 | 表示由软件自行计算 |
| 信号行第 9 字段 | V4 / MLIII |
导联名 | 逐记录不同,顺序即两路通道的顺序 |
注释行 #Age: |
如 62 |
受试者年龄 | 自由文本格式,需自行解析 |
注释行 #Sex: |
M / F |
性别 | 与年龄同行 |
| 注释行(无前缀) | 如 Mixed angina |
临床诊断与病理 | 行数不等,含诊断、血管病变、既往心梗 |
注释行 #Medications: |
如 nitrates, diltiazem |
用药 | 只有药名,无剂量与时程 |
注释行 #Recorder type: |
如 ICR 7200 |
记录仪型号 | 可用于设备异质性讨论 |
需要提醒:头文件里没有时间戳,没有记录编号向受试者 id 的显式映射。受试者身份只能靠官方给出的同源记录名单确定(§7.3)。
2.3 一条记录的完整解剖
以 e0103 为例。头文件首行是:
e0103 2 250 1800000
读法:记录名 e0103,两路信号,250 Hz,共 1,800,000 个采样点。1800000 ÷ 250 = 7200 秒 = 2 小时整。长度被精确切到整两小时,这让按分钟或按三十秒滑窗变得省事。
随后两行是通道声明:
e0103.dat 212 200 12 0 91 56457 0 V4
e0103.dat 212 200 12 0 751 48959 0 MLIII
这里有两个容易被跳过的点。其一是格式 212:这不是「每条样本两个字节」,而是 WFDB 的打包格式——相邻两个样本共占 3 字节,每个样本 12 位。正因为如此,.dat 的体积可以这样验证:每通道 1,800,000 个采样点,两通道合计 3,600,000 个样本,每两个样本打成 3 字节,正好是官方声明的 5,400,000 字节。用通用二进制读法把它当 int16 流直接读,只能读到一堆没有意义的数据。其二是增益 200:全库统一,因为原模拟记录里的标定信号被用来重新缩放,标定信号本身不进信号文件。
文件尾部是临床摘要:
#Age: 62 Sex: M
#Mixed angina
#1-vessel disease (RCA)
#Medications: nitrates, diltiazem
#Recorder type: ICR 7200
连起来读:六十二岁男性,混合型心绞痛,右冠状动脉单支病变,服用硝酸酯类与地尔硫䓬,记录仪为 ICR 7200。这段摘要是理解 ST 事件背景的关键——同样一段一百多微伏的偏移,出现在服用硝酸酯的冠心病患者身上与出现在健康人身上,含义完全不同。
读取信号与注释的标准写法:
import wfdb
from collections import Counter
#-- pn_dir 指向 PhysioNet 库名,可远程直读
rec = wfdb.rdrecord('e0103', pn_dir='edb')
ann = wfdb.rdann('e0103', 'atr', pn_dir='edb')
print(rec.fs, rec.sig_len, rec.sig_name) #-- 250 1800000 ['V4', 'MLIII']
print(rec.units, rec.adc_gain) #-- 增益 200,单位毫伏
print(rec.p_signal.shape) #-- (1800000, 2),已按增益换算
print(ann.sample[:5], ann.symbol[:5], ann.aux_note[:5])
#-- aux_note 即官方所说的文本字段,ST/T 事件的编码在里面
print(Counter(ann.symbol).most_common(8))
aux_note 是官方页面反复提到的「文本字段」。对该库而言,它不是一个可选的备注,而是 ST/T 事件的唯一载体——事件类型、通道号、峰值微伏数都编码在这串字符里。
2.4 注释类型字典
| 类型码 | 助记名 | 含义 | 出现形式 |
|---|---|---|---|
• |
NORMAL | 正常心搏 | 逐搏 |
a |
ABERR | 伴差异性传导的房性早搏 | 逐搏 |
J |
NPC | 交界性(结节性)早搏 | 逐搏 |
S |
SVPB | 室上性早搏或异位搏动 | 逐搏 |
V |
PVC | 室性早搏 | 逐搏 |
F |
FUSION | 室性与正常心搏的融合波 | 逐搏 |
Q |
UNKNOWN | 无法分类的心搏 | 逐搏 |
| `\ | ` | ARFCT | 孤立的类 QRS 伪迹 |
+ |
RHYTHM | 节律改变,具体类型在文本字段 | 事件 |
s |
STCH | ST 段改变,文本字段说明起止与峰值 | 事件 |
T |
TCH | T 波改变,文本字段说明起止与峰值 | 事件 |
| NOTE | NOTE | 注释型标注,用于轴偏移造成的假性改变 | 事件 |
| BUTTON | BUTTON | 受试者按下事件按钮 | 事件 |
| TS | TS | 磁带打滑 | 事件 |
qq |
NOISE | 信号质量改变,文本字段为两位字母 | 事件 |
需要说明一处细节:官方 annotations.shtml 的「Code」列只对心搏类给了字符(如 V、Q、|),对 RHYTHM、STCH、TCH、NOTE、BUTTON、TS 六行留空;NOISE 一行的助记名写作 qq。上表中 s 与 T 取自实际读到的注释类型字符;而官方 edb.txt 里那份年代较早的 rdann 样例输出,把 T 类标注打印成了小写 t。因此最稳的做法是不要靠类型字符做筛选(§5.6 第一条),改以文本字段的前缀判定事件。
节律改变的文本取值是固定的一组官方列表:
| 文本 | 含义 |
|---|---|
(AB |
房性二联律 |
(AFIB |
心房颤动 |
(B |
室性二联律 |
(B3 |
三度房室阻滞 |
(N |
正常窦性节律 |
(SAB |
窦房阻滞 |
(SBR |
窦性心动过缓 |
(SVTA |
室上性心动过速心律失常 |
(T |
室性三联律 |
(VT |
室性心动过速 |
信号质量注释 qq 的文本是两位字母,第一位描述信号 0、第二位描述信号 1:c 干净、n 有噪声、u 无法判读。官方给出的九种合法组合是 cc、nc、cn、nn、uc、un、cu、nu、uu。这个两位结构是宝贵的——它意味着「一路干净、一路噪声」这种常见情形不会被整段丢掉。
2.5 ST/T 事件的文本字段格式
这是整个库最独特的一处设计,也是最多人读错的地方。官方把一个完整事件拆成三个注释点:起始、极值、结束,且极值点携带峰值微伏数。
| 角色 | 文本字段形态 | 例子 | 解读 |
|---|---|---|---|
| 事件起始 | ( + 类型 + 通道 + 方向 |
(ST0- |
通道 0 上的 ST 压低事件开始 |
| 事件极值 | A + 类型 + 通道 + 方向 + 峰值微伏数 |
AST0-200 |
通道 0 ST 压低峰值 200 微伏 |
| 事件结束 | 类型 + 通道 + 方向 + ) |
ST0-) |
该 ST 事件结束 |
| T 波起始 | ( + T + 通道 + 方向 |
(T1+ |
通道 1 T 波正向改变事件开始 |
| T 波极值 | A + T + 通道 + 方向 + 峰值微伏数 |
AT1+350 |
通道 1 T 波改变峰值 350 微伏 |
| 极端 T 波 | ++ 或 -- |
(T0++ |
T 波偏差超过 0.4 毫伏的极端区间 |
| 轴偏移(假性 ST) | 小写 (st... |
(st1+ |
由体位改变造成、形似 ST 抬高的轴偏移 |
| 轴偏移极值 | 小写 at... |
at1+350 |
该假性改变的峰值 350 微伏 |
| 轴偏移结束 | 小写 st...) |
t1+) |
假性事件结束 |
官方给出的完整例子是:通道 0 上一次峰值压低 200 微伏的 ST 事件,会被写成三个连续的注释,文本字段分别是 (ST0-、AST0-200、ST0-)。小写写法专供轴偏移使用,官方解释是为了让人一眼区出「这是假的」。这类注释出现在六条记录里:e0161、e0509、e0601、e0611、e0613、e0615。
值得注意的是,edb.txt 里给出的样例输出本身就是一份教科书:从 (ST0+ 起,经 AT0+250、AST0+600、AST1-150,到 T0+)、ST1-)、ST0+) 结束,横跨约十分钟。它同时说明了一个事实:同一段时间里,通道 0 与通道 1 的事件可以不同步,两个通道各自独立判读、各自独立注释。
2.6 通道组合是浮动的
这是它与绝大多数现代心电库最大的规格差异。它不保证任何固定导联,每条记录的两路导联由原始研究组自定,写在头文件里。
| 记录 | 通道 0 | 通道 1 | 记录仪型号(头文件) |
|---|---|---|---|
| e0103 | V4 | MLIII | ICR 7200 |
| e0104 | MLIII | V4 | ICR 7200 |
| e0202 | V5 | MLI | Oxford Medilog MR-20 |
| e0305 | V2 | V5 | Oxford Medilog MR-35 |
| e0601 | V5 | MLIII | Del Mar Avionics 445B |
| e0817 | V5 | V1 | Oxford Medilog MR-14 |
| e1301 | V1 | V5 | Reynolds Tracker |
上表只是抽样,不能替代逐记录读取头文件。它想说明的是三件事:第一,抽样里反复出现的是 V4、V5 与改良肢体导联 MLIII、MLI;第二,同一记录的通道顺序在不同记录里可能颠倒(e0103 把 V4 放在通道 0,e0104 反过来),任何假设「通道 0 一定是胸导联」的代码都会出错;第三,设备型号随记录变化,这与这些记录来自多个国家研究组的背景一致。
这对算法评测有直接影响。要比较两个算法在同一批记录上的表现时,导联差异是一个必须携带的协变量:同一个 ST 事件在前壁导联上通常比在下壁导联上更醒目。把「它在 V4/MLIII 上的表现」写进结论,比写「它在这批数据上的表现」要诚实得多。
§3 它是谁的数据
3.1 贡献者
| 角色 | 机构与人员 | 出处 |
|---|---|---|
| 原始数据的驱动者 | 欧洲共同体「动态心电监护协同行动」(Concerted Action on Ambulatory Monitoring,项目 II.2.4,合同 MR049),1985 年启动 | thanks.shtml |
| 项目管理组 | D. Clement(比利时)、P. Coumel(法国)、C. Marchesi(意大利)、F. Stott(英国)、C. Zeelenberg(荷兰) | thanks.shtml |
| 继续开发并维护 | 意大利国家研究委员会(CNR)比萨临床生理研究所、荷兰鹿特丹 Erasmus 大学胸科中心 | thanks.shtml |
| 赞助与背书 | 欧洲心脏病学会(European Society of Cardiology)及其「心脏病学中的计算机」工作组 | 官方致谢段、thanks.shtml |
| 标注协作 | 来自八个国家的十三个研究组参与提供记录并完成标注 | thanks.shtml |
| 版权持有方 | European Society of Cardiology,1991 年 | edb.txt 文件头 |
| 上线与托管 | PhysioNet;2000 年首次上线,2009 年全量上线 | 官方版本历史 |
3.2 时间线
| 时间 | 事件 | 依据 |
|---|---|---|
| 1985 年 | 欧洲共同体「动态心电监护协同行动」启动,目标是为动态心电分析系统的质量评估定义一份心电数据库 | thanks.shtml |
| 1986 年 | 协同行动结束;比萨 CNR 临床生理研究所与鹿特丹胸科中心接手继续建设 | thanks.shtml |
| 1987 年 | 首批 ST-T 共同标准的方法论文献发表(Computers in Cardiology 14:63-68) | edb.txt 参考文献 1 |
| 1990 年 | 该库的开发、分发与使用说明发表(Computers in Cardiology 17:177-180) | edb.txt 参考文献 6 |
| 1991 年 | CD-ROM 版本完成;记录文件的时间戳统一停在这一年的 5 月 10 日 | edb.txt 版权行、文件目录 |
| 1992 年 | 主文献发表于 European Heart Journal 13:1164-1172 | 官方「请引用」段 |
| 2000 年 9 月 30 日 | 在欧洲心脏病学会支持下,近半部分在 PhysioNet/PhysioBank 上线 | 官方版本历史 |
| 2009 年 11 月 27 日 | 全库的九十段记录与参考注释文件整体上线,形成现今唯一的版本 1.0.0 | 官方版本历史 |
| 2015 年 8 月 19 日 | annotations.shtml 与 thanks.shtml 更新 |
文件目录时间戳 |
| 2019 年 2 月 20 日 | SHA256SUMS.txt 更新 |
文件目录时间戳 |
3.3 采集场景
记录来自动态心电(Holter)而非静息十二导联机。这意味着三件事:电极贴在体表随受试者活动、伪迹水平高于仰卧位采集、导联只能取两路。记录在时长上是选择一个两小时的节选而非全程,选择的目标不是「随机一天」,而是富集事件——官方明确说受试者全部为确诊或疑似心肌缺血,且额外选择标准意在取得代表性的心电异常集合,包括高血压、室壁运动障碍与药物效应导致的基线 ST 偏移。
记录仪型号在头文件里逐条给出,抽样可见 ICR 7200、Oxford Medilog MR-14/MR-20/MR-35、Del Mar Avionics 445B、Reynolds Tracker 等。这是一九八〇年代末的典型设备谱,也解释了为什么它里面的噪声形态与现代设备并不相同。
3.4 来源层次
要把它放到正确位置上,需要分清三层:原始劳动(八国十三研究组提供记录并完成标注)、整理与裁决(比萨协调组统一判据并处理分歧)、托管与分发(PhysioNet 2000 年起分两批上线)。许可证里的版权主体是欧洲心脏病学会,托管主体是 PhysioNet,二者不是一回事。
还有一个容易被忽略的层次:edb.txt 描述的其实是当年那张 CD-ROM,盘上除了本库之外还装有 VALE(VALidation-ECG)数据库——35 条记录、35 名受试者、每条约三小时单通道 200 Hz 采样。这个文件解释了为什么官方文案里会出现「近三百小时」与「近一百二十五万条注释」这类看起来与本库对不上的数字:那是整张盘的口径,而不是本库的口径。本库的口径是 90 段 × 2 小时,以及参考注释文件合计 802,866 条。
§4 它最独特的东西
4.1 稀缺性:一份「不复制别人」的标准
官方 thanks.shtml 里有一句自陈式的判断很重要:因为当时已经有了两个心律失常标准库(MIT-BIH 心律失常库与 AHA 室性心律失常检测器库),而缺少评价缺血检测器的东西,参与各方同意把精力集中到 ST 段与 T 波变化的标注规范上,使之成为补充而非复制。这句话解释了这个库的形状——它不是另一份「更大数据」的心律失常库,而是专门为一件别人没做的事做出来的。
这份稀缺性在三十多年后依然成立。绝大多数公开心电库围绕心搏分类与房颤检测组织;给出一次完整 ST 事件的三元组(起点、极值、终点),并附带以微伏为单位记录的手工峰值测量值的数据源,在公开领域里依然罕见。
4.2 差异化证据:两个人、两轮、一个裁决者
标注流程值得逐字重述,因为它决定了这些注释能被信任到什么程度。第一步,用一个对斜率敏感的 QRS 检测器跑出初始心搏标签,全部标为正常心搏。第二步,把每份两小时双通道记录按两分钟一页全文打印,页面上除了波形还有 QRS 检测标记、逐搏 ST 位移与 T 波幅度的趋势图,以及供勾选标注操作的方框。第三步,两位心脏病专家各自拿到全套打印件、每十秒一次的平均心率与 ST-T 参数趋势图、以及为该记录专门制作的透明塑料测量尺(尺上印着心率刻度与取自该记录头三十秒的参考 QRST 波群),独立地核对其中的每一个标签并插入 ST/T 形态、节律与信号质量改变的标注。第四步,比对两份结果,分歧交由协调组的一位心脏病专家裁决——官方承认这一步的前提是「裁决者因为同时看到两套标注而能做出更可靠的判断」。
这套流程的价值在于它把「主观性」暴露在明处:每个标注点背后是至少两双眼睛与一个裁决规则,而不是单次过目。它的代价也很清楚——没有任何文件记录参考波形到底取自头三十秒的哪一拍。官方对此坦白:这条信息没有被记录,原始塑料模板也已不存在,只能假定那条波形在当时具有代表性、且在噪声变化明显时偏向更干净的那一个。
4.3 具体案例:一个事件为何要写三行
把三类注释放在一起看最能体现设计意图。一次 ST 事件的完整描述需要起始、极值、结束三个注释;起始由「从偏移首次超过 0.1 毫伏的时刻向前回溯,直到找到一个偏移小于 0.05 毫伏、且此前三十秒内始终小于 0.1 毫伏的心搏」来确定,注释放在这个心搏之后;峰值由专家手工测量并写进极值注释的文本字段;结束则对称地向后回溯,注释放在那个心搏之前。
这样的三元组结构让三件事成为可能:验证一个算法是否检测到了事件(不必掐准终点)、验证它是否估对了峰值(峰值是独立给出的手工测量值)、以及验证它的事件边界是否稳定(因为有明确的回溯规则可以复算)。把它压成「这一段有事件」的二值标签会一次性丢掉这三样东西。
4.4 标注粒度:写在判据里的数字
| 判据项 | 取值 | 官方出处 |
|---|---|---|
| ST 测量点 | J 点后 80 毫秒;心率超过 120 次/分时为 60 毫秒 | annotations.shtml |
| ST 事件最短持续时间 | 30 秒 | annotations.shtml |
| ST 事件阈值 | 偏移绝对值 ≥ 0.1 毫伏 | annotations.shtml |
| 边界回溯判据 | 偏移 < 0.05 毫伏,且前后 30 秒始终 < 0.1 毫伏 | annotations.shtml |
| T 波事件最短持续时间 | 30 秒 | annotations.shtml |
| T 波事件阈值 | T 波偏移绝对值 ≥ 0.2 毫伏 | annotations.shtml |
| 极端 T 波阈值 | 0.4 毫伏,超出的区间另起注释标记起止 | annotations.shtml |
| 参考波形 | 取自每条记录头 30 秒内的一个典型波形,具体位置未记录 | annotations.shtml |
| 事件规模 | 367 段 ST 事件,401 段 T 波事件;另有 11 段假性 ST 改变的轴偏移与 10 段假性 T 波改变的轴偏移 | 官方 Data Description |
| 事件持续与峰值范围 | 30 秒至数分钟;峰值位移 100 微伏至逾 1 毫伏 | 官方 Data Description |
| 注释总数 | 参考注释文件合计 802,866 条 | 官方 Data Description |
4.5 边界条件:ST 电平与 ST 偏移,两条不同的曲线
这是使用它之前必须厘清的一处概念错位。官方在 annotations.shtml 里专门写了一节:部分受试者有陈旧心梗,因此存在固定的 ST 抬高或压低;这些记录上的 ST 注释标记的是叠加在固定抬高或压低之上的一过性改变。换句话说:
| 概念 | 定义 | 谁的参考点 |
|---|---|---|
| ST 电平函数 | 任一时刻的心电 ST 段幅度与等电位点幅度之差 | 无需参考 |
| 参考 ST 电平 | 记录头 30 秒期间的 ST 电平 | 头 30 秒 |
| ST 偏移函数 | 任一时刻的 ST 电平减去参考 ST 电平 | 头 30 秒 |
该库提供的是第三行的采样值,不是绝对电平。这意味着任何想用它的算法都必须自己先定一个参考 ST 电平(官方给了一个常用做法:取头 30 秒内 ST 电平测量值的中位数),再用自己的电平函数减去自己的参考电平,得到自己的偏移函数,然后才能与注释比对。把注释当绝对阈值二值化的做法,在概念上就不成立。
这件事的代价是评测流程多出一步:先得到一个偏移函数,再比较它。好处也同样实在——因为每个人的参考点不同,「这段基线本身就抬高了多少」被系统化地抵消掉了,剩下的才是真正由缺血引起的变化。对有陈旧心梗的受试者而言,这一层设计是唯一能让既有固定抬高与新发一过性缺血共存的处理方式。
§5 怎么拿到
5.1 目录结构与清单
| 路径层级 | 内容 |
|---|---|
https://physionet.org/files/edb/1.0.0/ |
根目录 |
├── e01xx. 至 e13xx. × 3 后缀 |
90 条记录:e0103–e0170、e0202–e0213、e0302–e0306、e0403–e0418、e0501–e0515、e0601–e0615、e0704、e0801–e0818、e1301–e1304 |
├── RECORDS |
90 条记录名清单 |
├── ANNOTATORS |
注释文件角色说明 |
├── annotations.shtml |
标注流程与判据文档 |
├── thanks.shtml |
致谢与贡献名单 |
├── edb.txt |
原始 CD-ROM 说明文本 |
└── SHA256SUMS.txt |
全部文件的 SHA256 校验和 |
记录名不是连续编号:缺失编号(例如 e0109、e0117、e0120)是常态,不要试图用等差数列推断记录数,直接读 RECORDS。
按前缀清点 RECORDS 可得到九个组号:e01xx 三十七条、e02xx 十一条、e03xx 五条、e04xx 十二条、e05xx 三条、e06xx 十四条、e07xx 一条、e08xx 四条、e13xx 三条。官方页面没有说明这些前缀的含义,因此它们只能作为分组线索,不能当作受试者或中心变量使用。
5.2 批量下载
官方在页面底部直接给出三种等价方式,全部无需注册、无需申请:
#-- 方式一:wget 镜像整个目录(-r 递归 -N 按时间戳 -c 断点续传 -np 不取上层)
wget -r -N -c -np https://physionet.org/files/edb/1.0.0/
#-- 方式二:AWS 命令行同步公共桶(无签名请求)
aws s3 sync --no-sign-request s3://physionet-open/edb/1.0.0/ ./edb/
#-- 方式三:页面上的 ZIP 包(约 465 MB),适合一次性取走
另外可以只列表或逐个取:https://physionet.org/files/edb/1.0.0/<文件名> 直链形式。下载完成后务必用 SHA256SUMS.txt 逐文件校验——这是目录里唯一一份可以用作完整性凭据的清单。
5.3 流式读取
不需要先落地全部数据。WFDB Python 包可以直接远程打开:
import wfdb
#-- 远程流式读:只取前 30 分钟,physical=False 保留整数以避免额外换算开销
rec = wfdb.rdrecord('e0105', pn_dir='edb', physical=False,
sampfrom=0, sampto=250 * 60 * 30)
print(rec.d_signal.shape, rec.sig_name)
#-- 注释同样支持远程
ann = wfdb.rdann('e0105', 'atr', pn_dir='edb')
注意 sampfrom 与 sampto 的单位是采样点而非秒,乘 250 换算。以 rolling 方式读长片段时,建议使用 rdrecord 的分段调用而不是一次性全读,两小时双通道在内存里不过几十兆字节,但对批量脚本而言远程反复 stream 会成为瓶颈。
5.4 转成表格
转成通用格式是常见需求,也是信息损失发生的地方:头文件里的增益、位分辨率、导联名、诊断文本要么被丢弃,要么被压成列名。如果需要转出,最稳的做法是同时导出两张表——一张宽表放波形,一张长表放注释。
import wfdb, pandas as pd
#-- 读记录与注释
rec = wfdb.rdrecord('e0105', pn_dir='edb')
ann = wfdb.rdann('e0105', 'atr', pn_dir='edb')
#-- 波形宽表:列采样点、两个导联名作为列
sig = pd.DataFrame(rec.p_signal, columns=['sig_' + n for n in rec.sig_name])
sig.insert(0, 'sample', range(rec.sig_len))
sig['time_s'] = sig['sample'] / rec.fs
#-- 注释长表:保留 aux_note 里的原始编码,不要提前解析
ann_df = pd.DataFrame({'sample': ann.sample,
'symbol': ann.symbol,
'aux_note': ann.aux_note})
ann_df['time_s'] = ann_df['sample'] / 250
ann_df.to_csv('e0105_annotations.csv', index=False)
关键纪律是:永远保留 aux_note 原串。一旦在导出时把它解析成「类型」「方向」「微伏」三列,就等于把官方的三元组结构拆成了三张互不相关的表,而事件三元组只有在合起来看时才有意义。
5.5 注释应该怎么读
| 你要的东西 | 怎么取 | 说明 |
|---|---|---|
| 所有 ST/T 改变注释 | 命令行 rdann -r <记录名> -a atr -p s t |
官方给出的标准做法,输出里含时间、采样点、类型、 aux 字段 |
| 事件起始 | aux_note 以 ( 开头 |
例如 (ST0-、(T1+ |
| 事件峰值 | aux_note 以 A 开头,后接三位或四位十进制数 |
末尾数字为峰值微伏数 |
| 事件结束 | aux_note 以 ) 结尾 |
与起始配对使用 |
| 所属通道 | 类型字母后的单个数字,0 或 1 |
与 rdrecord 的 sig_name 顺序对应 |
| 方向 | + 抬高 / - 压低;++ 与 -- 表示极端 T 波偏移 |
只出现在 T 类注释 |
| 真假之别 | 大写为真实 ST/T 改变,小写为轴偏移造成的假性改变 | 官方刻意用大小写区分 |
| 节律标签 | 类型码 + 且 aux 为 (AFIB、(N 等 |
只在节律改变的时刻出现,不是逐段标签 |
| 信号质量 | 类型码 qq,aux 为两位字母 |
第一位对应通道 0,第二位对应通道 1 |
5.6 七个坑
| 坑 | 现象 | 正确做法 |
|---|---|---|
把 .dat 当 int16 顺序读 |
波形完全错乱 | 格式是 212,两路 12 位打包。用 WFDB 或按 3 字节解两个 12 位样本 |
按小写 t 过滤 T 波改变 |
一条都抽不出来 | 文件里 T 类标注的类型字符是大写 T;而官方 edb.txt 那份年代较早的样例输出打印成了小写 t。改用文本字段前缀判定,别依赖类型字符 |
| 拿文本字段直接做相等比较 | ST0+) 比较失败 |
个别注释的 aux 字段尾部带补位的空字符 \x00,取值前先 strip('\x00') |
| 用文件时间戳区分上线批次 | 全部记录文件都显示 1991-05-10 | 批次信息在官方版本叙述里(2000 年 48 条 / 2009 年全量),不在文件系统里 |
直接读 edb.txt 里提到的样例记录 x_edb |
目录里没有这个文件 | 该文件属于原始 CD-ROM,PhysioNet 1.0.0 目录中不存在;想要十二分钟短样例需自己从 e0105 开头截取 |
| 把 200 ADC 单位/毫伏 当通用常数 | 换库后幅度全错 | 这是本库统一重标定的结果;不同库增益不同,一律从 .hea 读 |
| 把「注释总数」当「心搏数」 | 802,866 远大于合理心搏量 | 该数字包含 ST/T 三元组、节律切换、信号质量等全部注释类型 |
| 用 0.1 毫伏绝对阈值直接二值化 | 与参考标注系统性错位 | 注释是相对头 30 秒参考波形的偏移,算法需自建参考电平后再比对 |
§6 与库内条目的关系
6.1 关系图谱
| 站内数据集 | 与本库的边界 | 什么时候选它 |
|---|---|---|
| 长时程心电记录库 — LTSTDB 缺血与非缺血事件参考集 | 同为缺血 ST 评测,但 LTSTDB 每条 21–24 小时、80 名受试者 86 条记录,提供三套不同判据下的 ST 事件注释与 ST 电平/偏移函数文件 | 需要长时程、需要三档阈值对照、需要 ST 电平函数本身 |
| 十二导联做满半小时 — INCART 心律失常库 | 同为 Holter 来源,但 INCART 保留十二导联、每段 30 分钟、257 Hz | 需要跨导联一致性、需要十二导联形态,不需要 ST 事件判据 |
| 房颤什么时候自己停 — AF Termination Challenge 心电库 | 专注房颤终止预测,与本库的缺血定位无关 | 做房颤节律任务 |
| LTAFDB | 长时程房颤库 | 做长时程房颤负荷,而非 ST 事件 |
| 专挑难压的二十秒 — MIT-BIH 心电压缩测试库 | 压缩/波形保真任务,与缺血无关 | 做心电压缩与重建评测 |
| 房颤预测的元祖赛题 — PAF 预测挑战赛数据库 | 阵发性房颤预测,长短记录配对 | 做房颤发作前预测 |
| WCTECGdb:威尔逊中心电端 37 路直接测量 | 心电导联物理本质的直接测量,与本库的应用层评测互补 | 需要理解导联本身是怎么来的 |
| Georgia 12-Lead ECG Challenge Database | 十二导联大规模诊断分类 | 需要大样本十二导联分类基准 |
| ECG-Image-Database — 大规模成对心电图图像与数字波形库 | 纸质/图像心电数字化,与本库无关 | 做图像心电还原 |
| PhysioNet/Computing in Cardiology Challenge 2011 | 挑战赛形式的十二导联短片段任务 | 需要竞赛榜单与标准评测脚本 |
6.2 检索路径
要在这批数据集里定位自己需要的那一个,按三个问题依次问下去最快:
- 任务对象是 ST/T 幅度还是心搏类别? 前者在本库与 LTSTDB 之间选,后者去心律失常库。
- 需要多长的时间覆盖? 小时级以内(本库)与日级(LTSTDB)是两个完全不同的工作量级,差的不是数量而是能否回答负荷类问题。
- 需要多少导联? 两路(本库)与十二导联(INCART、Georgia)之间的差别,决定了能不能做定位类任务。
6.3 分工判据:三库对照
| 维度 | European ST-T Database(本库) | LTSTDB | INCART |
|---|---|---|---|
| 定位 | ST/T 变化的评测标准 | 长时程 ST 事件的参考集 | 十二导联心律失常与跨导联一致性 |
| 记录数 | 90 段 | 86 条 | 75 段 |
| 受试者 | 79 名 | 80 名 | 32 名 |
| 单条时长 | 2 小时 | 21–24 小时 | 30 分钟 |
| 通道数 | 2 | 2 或 3 | 12 |
| 采样 | 250 Hz,12 位,20 毫伏量程 | 250 Hz,12 位,±10 毫伏 | 257 Hz,16 位存储 |
| 标注重心 | ST/T 事件三元组 + 逐搏 + 节律 + 质量 | ST 事件(三套判据)+ ST 电平与偏移函数 | 逐搏心搏类型 |
| 每条文件数 | 3 | 12 | 3 |
| 许可 | ODC-BY 1.0 | 同类开放许可 | ODC-BY 1.0 |
三者之间的关系是互补的:本库给出短时段内的精细判据与专家裁决,LTSTDB 给出全天的事件密度与多档阈值,INCART 给出导联维度。真正严肃的评测通常先用本库对齐判据,再用 LTSTDB 验证长时程表现。
§7 质量评估与局限性
7.0 前置校正
讨论它的数据质量之前有三件事必须先说清:第一,全库只有一个版本(1.0.0),不存在「用新版本修正老版本」的路径,任何官方层面的修订都只会以文件重发的形式出现;第二,记录文件的 mtime 统一为 1991-05-10,不能用它判断上线批次;第三,SHA256SUMS.txt 在 2019 年更新过一次,它是当前唯一可以校验到的完整性凭据。
7.1 五维评分
| 维度 | 判断 | 理由 |
|---|---|---|
| 标注可信度 | 高 | 两位专家独立 + 第三方裁决的四步流程,判据写成了明确规则 |
| 规则可复算性 | 高 | 测量点、最短时长、阈值、回溯规则全部公开且互相自洽 |
| 纵向一致性 | 中 | 参考波形位置未记录、塑料模板已丢失,理论上存在不可复算的成分 |
| 人群代表性 | 低 | 79 人,男性 70 名与女性 8 名(另 1 名缺失),且全部为确诊或疑似缺血 |
| 工程可用性 | 中 | 12 位打包格式、浮动导联、缺失的诊断字段,都需要额外的处理代码 |
7.2 标注的两层
第一层是几何层:心搏位置与 ST/T 测量点。这一层的客观性来自判据——J 点后 80 毫秒的定义不因判读者而变,理论上可以复算。第二层是语义层:某一段变化能不能称为一次事件、峰值该取在哪个心搏上。这一层的判读依赖于专家对波形形态的主观判断,两位专家的分歧正是出现在这一层,裁决机制也是为它而设。
理解这两层的区别很重要:把它用于算法评测时,实际上是在让算法复现第一层的几何判断与部分第二层的语义判断。算法在事件边界附近丢分,往往不是它没有检测到变化,而是它选的极值心跳与专家选的不是同一个。
7.3 可枚举偏差
| 偏差来源 | 具体形态 | 影响 |
|---|---|---|
| 同源受试者泄漏 | 官方列出七组重复:e0118–e0122、e0123–e0126、e0129 与 e0133、e0136 与 e0139、e0147 与 e0148、e0154 与 e0155、e0162 与 e0163 | 按记录随机划分时,同一个人的片段会同时出现在训练与测试侧 |
| 性别构成 | 70 名男性、8 名女性,1 名信息缺失 | 任何性别分层的结论都缺乏基础 |
| 受试者与记录数不一致 | 官方声明 79 名受试者与 90 段记录,按上述七组重复折算后仍有一名的缺口,页面未说明原因 | 分组变量存在不可解的不确定性 |
| 人群富集 | 全部为确诊或疑似心肌缺血,并刻意纳入由高血压、室壁运动障碍、药物造成的基线 ST 偏移 | 「正常」样本的代表性不足 |
| 设备异质性 | 记录仪型号随记录变化(ICR、Oxford Medilog、Del Mar Avionics、Reynolds 等) | 既有利于泛化讨论,也意味着单记录噪声水平波动大 |
| 导联不一致 | 每记录两路,组合与顺序都不同 | 跨记录聚合结果会被导联差异污染 |
| 时间窗口截断 | 每段仅两小时节选,并非完整 24 小时 | 不能用于负荷、昼夜节律或全天事件频率 |
7.4 外部验证的必要性
上面列出的每一项偏差都不能靠在库内换一种切分方式消掉:它的内部自洽性很高,但这不等于它在别的场景里有效。任何一个在该库上跑出理想成绩的算法,还应再做两件事:一是换到长时程库上验证表现是否稳定;二是明确报告目标导联组合,避免把「在 V4/MLIII 上的表现」说成「在动态心电上的表现」。
7.5 它为何还在
一个 1991 年完成、1992 年发文的库,到今天仍是 ST-T 分析评测的默认参照物,原因不在数据量而在制度性:它的判据写进了公开文献,它的记录名出现在大量论文的方法节里,而 AAMI EC38 与 EC57 两项标准把它所在的评测口径纳入了正式框架。换用一个规模更大的新库,意味着与三十年的公开结果失去可比性——这个代价大到没有理由付出。
§8 生态位与历史
8.1 沿革
| 阶段 | 时间 | 关键动作 |
|---|---|---|
| 立项 | 1985 | 欧洲共同体协同行动定义目标:为动态心电分析系统质量评估做一份标准数据库 |
| 分工决策 | 1985–1986 | 已有两个心律失常标准库,决定聚焦 ST-T 变化,做成补充而非重复 |
| 建设 | 1986–1991 | CNR 比萨与鹿特丹胸科中心牵头,八国十三研究组提供记录与标注劳动,ESC 提供资助与背书 |
| 固化 | 1991 | CD-ROM 发行 |
| 文献化 | 1992 | European Heart Journal 主文献发表,成为引用的固定锚点 |
| 分发 | 2000 / 2009 | 分两批进入 PhysioNet,形成唯一版本 1.0.0 |
8.2 与挑战赛
官方把它列为一个独立的数据库项目,并未以「挑战赛」形式发布。它的评测属性更多是通过标准文档起作用——官方把 ANSI-AAMI EC38(动态心电记录仪)与 EC57(心律与 ST 段测量算法性能测试与报告)列为参考文献,这两份标准描述的正是如何报告算法在 ST 测量上的表现。因此它是标准文档的实践载体,而不是榜单型数据集。这决定了它的使用方式:不是参加比赛,而是自己按文档口径跑一次合规性测试。
8.3 生态位
在动态心电的公开数据版图里,它占据的是「ST/T 变化的裁决者」这一格。相邻格子里分别是:心律失常标准的提供者(MIT-BIH 系列)、长时程 ST 事件参考(LTSTDB)、十二导联形态(INCART、Georgia 等)、以及各类挑战赛榜单。它的不可替代性来自两点——专家双盲标注加裁决的流程,以及把「参考电平」这一层思考写进了数据本身的注释设计。
还要看清它在「评测方法」层面的位置。多数主流心电评测用的是分类指标(敏感度、特异度、F1),而它要求的是估计量层面的比较:算法输出的一条连续偏差曲线,要与专家给出的离散采样点逐一对照。这两类评测的组织方式完全不同——前者只要有标签就能算,后者要处理时间对齐、阈值回溯与双侧边界判定。这正是它门槛偏高、却始终没有同类替代物的原因。
一个务实的使用建议是把它与长时程库搭配:用长时程库做训练与筛查,用它做校准与收尾。两者结合得到的东西,比单独使用任何一方都更接近真实的动态心电分析链路。
8.4 谁在用
四类人会真正打开它:一是开发 Holter 分析软件的工程团队,需要标准合规的可比数字;二是做缺血检测算法的学术研究者,需要能与既有文献对照的外部测试集;三是做心电标准化的机构与监管相关人员,需要按 EC57 类口径测试;四是教学场景里讲动态心电 ST-T 判读的教师,需要一批带标准答案的两小时片段。
§9 使用指引
9.1 三种角色的路径
| 角色 | 建议路径 | 关键动作 |
|---|---|---|
| 算法工程师(ST 分析) | 读判据 → 实现自己的偏移函数 → 对齐事件三元组 → 统计矛盾率 | 参考电平务必自己取;优先用 rdann -p s t 导出的标准输出做比较 |
| 研究者(缺血检测) | 作为外部测试集使用,训练另找大库 | 报告时写明采用了哪批记录、哪个导联组合 |
| 标准合规/评测人员 | 按 EC38/EC57 的口径组织指标 | 使用 annotations.shtml 里的原始判据,不要改用自定义阈值 |
| 教师 | 取单条记录做完整事件讲解 | 用 e0105 段头的那次完整事件,起始、极值、结束三个注释点都能讲到 |
9.2 最短流程
import wfdb
#-- 1) 读记录,确认导联顺序与增益
rec = wfdb.rdrecord('e0105', pn_dir='edb')
print(rec.sig_name, rec.adc_gain, rec.units) #-- 例如 ['V4','MLIII'] [200 200]
#-- 2) 读注释,保留原始 aux 文本
ann = wfdb.rdann('e0105', 'atr', pn_dir='edb')
#-- 3) 挑出 ST/T 改变注释:按文本字段判定,不依赖类型字符的大小写
st_t = [(s, a) for s, a in zip(ann.sample, ann.aux_note)
if re.match(r'^\(?A?[SsTt][01]', a)]
#-- 4) 大写 ST/T 为真实事件,小写 st/t 为轴偏移造成的假性改变
real = [x for x in st_t if re.match(r'^\(?A?[ST]', x[1])]
pseudo = [x for x in st_t if re.match(r'^\(?A?[st]', x[1])]
#-- 5) 起始、峰值、结束三元组:分别为 '(' 开头、'A' 开头、')' 结尾
begins = [x for x in real if x[1].startswith('(')]
peaks = [x for x in real if x[1].startswith('A')]
ends = [x for x in real if x[1].rstrip('\x00').endswith(')')]
print(len(st_t), len(begins), len(peaks), len(ends))
9.3 引用方式
官方要求引用原始发表于 European Heart Journal 的论文,并同时给出 PhysioNet 的标准引用。
#-- 原始文献(官方指定)
Taddei A, Distante G, Emdin M, Pisani P, Moody GB, Zeelenberg C, Marchesi C.
The European ST-T Database: standard for evaluating systems for the analysis
of ST-T changes in ambulatory electrocardiography.
European Heart Journal 13: 1164-1172 (1992).
https://www.ncbi.nlm.nih.gov/pubmed/1396824
#-- PhysioNet 平台引用(官方提供 BibTeX/APA/MLA 等多种格式)
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). https://doi.org/10.1038/s44360-026-00096-z
#-- 数据集版本与标识符
European ST-T Database, version 1.0.0. https://physionet.org/content/edb/1.0.0/
DOI: 10.13026/C2D59Z
§10 AI 使用声明
| 项 | 说明 |
|---|---|
| 文本生成 | 由 AI 起草,经人工核对结构与用词 |
| 数字来源 | 全部取自 PhysioNet 官方页面 https://physionet.org/content/edb/1.0.0/ 目录下的文件(Data Description 段、annotations.shtml、thanks.shtml、edb.txt、ANNOTATORS、RECORDS、SHA256SUMS.txt 及文件时间戳) |
| 文件核验 | 已核对文件目录:90 条记录各含 .hea/.dat/.atr 三个文件,另有 6 个附属文件,合计 276 个;.dat 均为 5,400,000 字节 |
| 不一致说明 | 官方 edb.txt 中的「近三百小时」「近一百二十五万条注释」为该 CD-ROM 的总口径(含 VALE 库 35 条记录,其参考注释文件为 438,642 条),与本库的 802,866 条不同源不同义;官方同时声明 79 名受试者与七组重复记录,折算后的缺口页面未解释,已在 §7.3 列出 |
| 论文信息 | Taddei 等,European Heart Journal 13:1164-1172 (1992),PMID 1396824;PhysioNet 平台主文 Nature Health (2026) |
| 未核验内容 | 各记录的逐搏标注类型构成、ST 事件的导联归属、峰值位移的分布形态等一概未做;edb.txt 提到的样例记录 x_edb 在当前 1.0.0 目录中不存在,其在原始 CD-ROM 中的实现细节亦未验证 |
| 图像 | 封面图为风格化生成图像,非真实设备照片,图中标注仅供示意 |
| 免责 | 该数据集仅用于算法研究与教学,不构成诊断依据,不得直接用于临床决策 |
常见误读(避坑清单)
| 说法 | 实际 | 证据 |
|---|---|---|
| 它是十二导联库 | 每条记录只有两路信号 | 头文件信号行只有两行;官方写明 contains two signals |
| 每段是二十四小时 Holter 全程 | 每段固定两小时节选 | 头文件第 1 行第四字段为 1800000,除以 250 得 7200 秒 |
| 注释给的是绝对 ST 电平 | 给的是相对头 30 秒参考波形的偏移 | annotations.shtml 专节讨论 ST 电平函数与 ST 偏移函数之别 |
| 八十万条注释都是心搏 | 802,866 条含 ST/T 三元组、节律、信号质量等全部类型 | ANNOTATORS 一行写明 atr 的角色为 beat、rhythm、ST/T change、signal quality |
| 九十段来自九十个人 | 79 名受试者,官方点名七组重复记录 | 官方 Data Description 括号内的名单 |
| 许可机制和 CC-BY 一样 | 是 Open Data Commons Attribution License v1.0 | 页面 Access 段 |
| 2009 年才第一次公开 | 2000 年 9 月已上线近半,全部注释文件当时就已上线 | 官方两条版本历史 |
可以用 (AFIB 标签做房颤二分类 |
节律注释只标记切换时刻,不是逐段标签 | 注释类型表中 RHYTHM 项说明 |
.dat 每采样点两字节 |
212 打包格式,两点共 3 字节 |
文件体积 5,400,000 与点数吻合;头文件格式字段为 212 |
| 通道 0 一定是胸导联 | 通道顺序逐记录浮动 | e0103 为 V4+MLIII,e0104 为 MLIII+V4 |
| 文件时间戳能区分上线批次 | 全部记录文件都显示 1991-05-10 | 文件目录列举的时间戳 |
edb.txt 里的记录数和本库一致 |
该文件描述的是含 VALE 库的整张 CD-ROM | edb.txt 目录结构与 VALE 章节 |
FAQ
Q1:它能不能直接拿来做深度学习训练集?
不太行,也不该这么用。九十段记录、367 段 ST 事件与 401 段 T 波事件,这个规模放在现代深度模型面前会被一两轮记住。它的正确用法是外部测试集与评测集:先在别的大库上训练,再用它按官方判据对齐口径,得到可与公开文献比较的数字。硬要做训练,至少要严格按受试者分组,并接受事件量级过小的事实。
Q2:为什么官方说注释是「相对的」,这对我有什么影响?
因为注释的是 ST 偏移函数,参考点取在每条记录头三十秒。影响是根本性的:你的算法必须先自己估计一个参考 ST 电平(常用做法是取头三十秒内电平测量值的中位数),再用自己的电平函数减去这个参考电平得到偏移函数,最后才能与注释比对。直接把注释当绝对阈值二值化,等于在两个不同的零点之间做对比。
Q3:九十段和七十九个人之间差在哪里?
官方直接点出了七组同源记录:e0118–e0122、e0123–e0126、e0129 与 e0133、e0136 与 e0139、e0147 与 e0148、e0154 与 e0155、e0162 与 e0163。按这些组折算后仍存在一名受试者的缺口,官方页面没有说明原因——这属于应采用谨慎处理的未知项,写在 §7.3 里。工程上的结论很明确:按受试者分组时只能用官方给出的名单,不能假定「每条记录一个人」。
Q4:它和 LTSTDB 该选哪个?
取决于时间覆盖与判据需求。它给的是两小时的精细段、一套判据、双盲加裁决的流程;LTSTDB 给的是 21–24 小时的全程记录、八十名受试者与八十六条记录、三套不同判据下的事件注释(Vmin 取 75 或 100 微伏、Tmin 取 30 或 60 秒),以及 ST 电平与偏移函数的现成文件。想要快速对齐口径用以比较,用它;想要验证长时程与阈值敏感性,用 LTSTDB。严肃的评测往往两个都跑。
Q5:为什么它的注释总数在不同地方写着不一样?
因为范围不同。edb.txt 描述的是当年那张 CD-ROM,其中包含本库之外的 VALE 库,它给出的「近三百小时」「近一百二十五万条注释」是整盘的口径。而页面上「参考注释文件合计 802,866 条」是指本库九十段记录的 .atr 文件。两者都没有错,引用时必须指明范围。
术语表
| 术语 | 英文原名 | 含义 |
|---|---|---|
| ST 段 | ST segment | QRS 波群终点至 T 波起点之间的心电区间,其位移是心肌缺血的重要表征 |
| T 波 | T wave | 心室复极对应的波形,振幅与方向的改变同样具有诊断意义 |
| 动态心电 | Ambulatory ECG / Holter | 受试者佩戴记录仪在日常活动状态下的长时间心电采集 |
| J 点 | J point | QRS 波群与 ST 段的交界点,ST 位移测量的时间原点 |
| ST 电平函数 | ST level function | 任意时刻 ST 段幅度与等电位点幅度之差 |
| ST 偏移函数 | ST deviation function | ST 电平函数减去参考 ST 电平的函数,本库注释的对象 |
| 事件三元组 | episode triple | 起始、极值、结束三个注释点构成的完整事件描述 |
| 辅助信息字段 | aux field / aux_note | 注释中携带的文本字符串,本库用它编码事件类型、通道、方向与峰值 |
| 轴偏移 | axis shift | 体位改变导致心电轴变动,形似 ST/T 改变但并非缺血所致 |
| 改良肢体导联 | Modified limb lead(MLI/MLIII) | Holter 常用的肢体导联改接方式,信号更稳定 |
| 打包格式 212 | format 212 | WFDB 的一种存储方式,相邻两个 12 位样本共占 3 字节 |
| WFDB | WaveForm DataBase | PhysioNet 使用的波形与注释文件格式体系 |
| ODC-BY | Open Data Commons Attribution License | 要求署名的开放数据许可;本库采用 v1.0 |
| 信号质量注释 | NOISE annotation | 用两位字母标记两路通道质量的注释,取值含 c、n、u 三类字符组合 |
| 极端 T 波偏移 | extreme T deviation | T 波偏移超过 0.4 毫伏的区间,在该库中额外单独标注 |
附录 A:核心数字核对表
| 数字 | 出处 |
|---|---|
| 90 段记录 | RECORDS 计数与官方 Data Description |
| 79 名受试者 | 官方 Data Description |
| 70 名男性 30–84 岁 | 官方 Data Description |
| 8 名女性 55–71 岁 | 官方 Data Description |
| 1 名受试者信息缺失 | 官方 Data Description |
| 每段 2 小时 | 官方 Data Description 与 .hea 首行 1800000 |
| 1,800,000 采样点 | .hea 首行第四字段 |
| 250 Hz | .hea 首行第三字段 |
| 12 位分辨率 / 20 毫伏标称输入范围 | 官方 Data Description |
| 200 ADC 单位/毫伏 | 官方 Data Description 与 .hea 增益字段 |
| 每段信号文件 5,400,000 字节 | 官方 Data Description 与文件目录里的文件大小 |
| 总未压缩体积 465.1 MB | 官方 Files 段 |
| 参考注释合计 802,866 条 | 官方 Data Description |
| 367 段 ST 事件 | 官方 Data Description |
| 401 段 T 波事件 | 官方 Data Description |
| 11 段轴偏移致假性 ST 改变、10 段致假性 T 改变 | 官方 Data Description |
| 事件持续 30 秒至数分钟 | 官方 Data Description |
| 峰值位移 100 微伏至逾 1 毫伏 | 官方 Data Description |
| ST 事件阈值 0.1 毫伏 / 最短 30 秒 | annotations.shtml |
| T 波事件阈值 0.2 毫伏 / 极端阈值 0.4 毫伏 | annotations.shtml |
| 测量点 J 点后 80 毫秒(心率 >120 次/分时为 60 毫秒) | annotations.shtml |
| 2000 年上线 48 条完整记录与全部参考注释文件 | 官方 Data Description 末段 |
| 2009 年 11 月 27 日全量上线 | 官方版本历史 |
| DOI 10.13026/C2D59Z | 官方 Discovery 段 |
| 文件总数 276(90 × 3 + 6) | PhysioNet 文件目录计数 |
| 360 小时总时长(90 段 × 2 小时) | 由官方 Data Description 的两项数字直接相乘 |
相关数据集导航
| 站内数据集 | 链接 |
|---|---|
| 长时程心电记录库 — LTSTDB 缺血与非缺血事件参考集 | https://www.qianfanghub.com/ai-ready-dataset/ltstdb/1493 |
| 十二导联做满半小时 — INCART 心律失常库 | https://www.qianfanghub.com/ai-ready-dataset/incartdb/1440 |
| 房颤什么时候自己停 — AF Termination Challenge 心电库 | https://www.qianfanghub.com/ai-ready-dataset/aftdb/1457 |
| LTAFDB | https://www.qianfanghub.com/ai-ready-dataset/ltafdb/668 |
| 专挑难压的二十秒 — MIT-BIH 心电压缩测试库 | https://www.qianfanghub.com/ai-ready-dataset/cdb/1506 |
| 房颤预测的元祖赛题 — PAF 预测挑战赛数据库 | https://www.qianfanghub.com/ai-ready-dataset/afpdb/1435 |
| WCTECGdb:威尔逊中心电端 37 路直接测量 | https://www.qianfanghub.com/ai-ready-dataset/wctecgdb/1311 |
| Georgia 12-Lead ECG Challenge Database | https://www.qianfanghub.com/ai-ready-dataset/georgia-12-lead-ecg-challenge/1141 |
| ECG-Image-Database — 大规模成对心电图图像与数字波形库 | https://www.qianfanghub.com/ai-ready-dataset/ecg-image-database/959 |
| PhysioNet/Computing in Cardiology Challenge 2011 | https://www.qianfanghub.com/ai-ready-dataset/cinc-2011/689 |
导航说明: 上表中的链接均为站内已上架条目,按「同为 ST/T 评测 → 同为动态心电 → 同为心电基准」的顺序排列。若要在它们之间做选择,先按 §6.2 的三个问题确定任务对象、时间覆盖与导联需求,再回到本速览表核对规模与许可。

