QT 延长不是一件事 — ECGRDVQ 药物复极库

22 人 5 期交叉 / 12 导联 10 秒 / 中位搏标注

来源 https://physionet.org/content/ecgrdvq/1.0.0/发布时间: 2026-10-28最后更新: 2026-10-28 阅读 13
QT 延长不是一件事 — ECGRDVQ 药物复极库

信息速览

数据集名称QT 延长不是一件事 — ECGRDVQ 药物复极库
数据类型时序信号,波形,人工标注,元数据
规模22 名受试者 / 5232 段心电
接入方式https://physionet.org/content/ecgrdvq/1.0.0/
AI 就绪度

同一段 QT 间期,可能是纯粹的钾通道阻滞造成的,也可能是钾通道被堵住、同时钙或晚钠电流也被压住造成的。前者把复极的早段与晚段一起拉长,后者会把早段反向拉短——两者在纸面上都可能只表现为 QT 延长了三十毫秒,致心律失常的风险却不是一回事。要证明这一点,靠回顾性数据不行,必须让同一批人依次吃下作用机制不同的几种药,再在固定时点上反复测量。

ECGRDVQ 就是为此做的。二十二名健康志愿者,五个给药期,四种已知延长 QT 的药物加安慰剂,每期连续记录二十四小时心电,在十六个名义时点各抽三份十秒十二导联片段。它把「药物—浓度—复极形态」三件事钉在同一条时间轴上,同时给出原始波形和中位搏上的复极界标,让「QT 延长」这个笼统指标第一次可以被拆成两段来看。

它的短板和长处一样醒目:人少、中心单一、没有结局事件、片段还是软件挑出来的最干净的那三条。它不能证明某种药会不会真的引起尖端扭转型室速,只能证明复极的两段被怎样分开拉扯。一屏速览见下表。

维度 内容
全名 ECG Effects of Ranolazine, Dofetilide, Verapamil, and Quinidine
缩写 ECGRDVQ(四个药名首字母)
发布方 PhysioNet,数据由美国 FDA 与 Spaulding Clinical Research 提供
首次发布 2016 年 7 月 26 日,版本 1.0.0
受试者 22 名健康志愿者
设计 随机、双盲、五期、安慰剂对照交叉,期间洗脱 7 天
处理 雷诺嗪 1500 mg、多非利特 500 μg、维拉帕米 120 mg、硫酸奎尼丁 400 mg、安慰剂
心电规模 5,232 段十秒十二导联片段
中位搏 5,223 条,附半自动复极界标
时点 16 个(给药前 1 个、给药后 15 个)
每点重复 3 份,要求心率稳定、信号质量最优
采集 500 Hz 连续记录,幅度分辨率 2.5 μV;发布时上采样至 1000 Hz
导联 标准十二导联;中位搏另含向量合成导联与三个正交分量
附带表 SCR-002.Clinical.Data.csv,一行一段心电,33 列
文件格式 WFDB:.hea 头文件 / .dat 信号 / .atr 注释(仅中位搏)
体积 解压后 1.4 GB
许可 ODC-BY 1.0,无需注册
DOI 10.13026/C2HP45

§1 它要解决的具体麻烦

1.1 一个数字承担了它承担不了的分量

药物心脏安全性评价在过去二十年里被一个指标统治:QT 间期。它好测、好比较、好写进指导原则,于是成了「这颗药会不会引发致命心律失常」的代理。问题在于,QT 是从 QRS 起点到 T 波终点的一整段时间,中间没有任何分界。钾通道被堵住会让它变长,钙通道被堵住会让它变短,晚钠电流被增强或抑制也会改变它,自主神经张力、心率、体位、甚至一顿饭都会动它。同一个延长的数值,可以是安全的,也可以是危险的。

官方引用的那篇临床试验论文把这件事说得更直接:单纯阻滞 hERG 钾通道的药物,会把复极的早期和晚期一起拉长;而同时阻滞钙通道或晚钠通道的药物,会在拉长晚期的同时把早期缩短。两股力量相互抵消,总 QT 看起来变化不大,但复极的形态已经不一样了。要看到这个差别,必须把 QT 切成两段分别测——早期用 J 点到 T 波峰(J-Tpeak),晚期用 T 波峰到 T 波终点(Tpeak-Tend)。

这个观察需要一个特殊的数据结构来支撑:同一批人、同一天里、同一套电极下,分别接受作用机制不同的药物,且血药浓度要能对上心电。常规的临床心电库给不了这个结构,因为它们记录的是不同的人在不同状态下的十秒图,人与人之间的差异远大于药物带来的差异。ECGRDVQ 的全部设计都围绕这一点展开。

处理 主要通道作用 对复极早期 对复极晚期
多非利特 纯 hERG 阻滞 延长 延长
奎尼丁 hERG 为主,兼有钙与晚钠阻滞 延长幅度较小 延长
雷诺嗪 hERG 加晚钠阻滞 被部分抵消 延长
维拉帕米 hERG 加 L 型钙阻滞 明显被抵消 延长
安慰剂 无 基线 基线
指标 覆盖的复极阶段 主要反映什么
QT 全程 复极总时长,机制混杂
QTc 全程、按心率校正 同上,去掉了心率影响
J-Tpeak 早期 平台期内外向电流的平衡
Tpeak-Tend 晚期 跨壁复极离散的代理
T 波振幅与平坦度 形态 复极在空间上的均一性

1.2 三条常见的错误期待

第一条,期待它是「心电质量库」。缩写里的 RDVQ 是四个药名的首字母,不是任何质量评分体系的代号。这份数据里没有任何一段被标为可用或不可用,恰恰相反,官方的抽取流程是让软件在每个时点挑出信号质量最好的三条,噪声段在源头就被丢掉了。拿它做质量分类,等于拿筛选后的样本去学筛选规则。

第二条,期待它是「大样本的十二导联库」。二十二个人、五千多段十秒图,听起来不少,但按人一分,训练侧只剩十几个人。它的统计效能来自同一批人反复测量(每人每期四十八条),而不是来自人群广度。任何以「人多」为前提的任务——人群分布建模、罕见形态发现、跨中心泛化——在这里都会落空。

第三条,期待它能回答「这药到底危不危险」。它记录的是健康志愿者单次给药后二十四小时内的复极改变,没有随访、没有不良事件、没有尖端扭转型室速发生。它提供的是机制层面的替代终点,不是结局。把它当成药物风险的金标准,是把替代指标当成了终点本身。

1.3 它能给到的与给不到的

你的需求 它给的 够不够
复极界标算法的评测真值 五千余条中位搏,六类界标的半自动标注 够,是目前少数带 J-Tpeak 与 Tpeak-Tend 标注的公开数据
浓度-效应建模 每个时点一条血药浓度,与三份心电对齐 够做暴露-反应曲线,但每点仅一个样本
区分早期与晚期复极 同批人、四种机制、完整时点序列 够,这是它存在的理由
逐搏 QT 变异性研究 中位搏抹掉了逐搏差异 不够,需回到原始段自行检测
心电信号质量评估 无任何质量标签,且片段已被择优 完全不够,方向相反
病理形态分类训练 全部健康志愿者,无疾病标签 不够,标签是药物不是诊断
尖端扭转型室速风险预测 无结局事件 不够,只能做替代终点的验证
算法跨中心泛化测试 单一临床中心、单一设备链 不够,只能做跨库而非跨中心
教学演示药物对复极的影响 同一人五种处理、十六个时点 够,且比教科书插图更有说服力

1.4 你的处境与它能帮到的事

你的处境 它能帮你什么 下一步该做什么
你在做 T 波终点检测,苦于没有带 J-Tpeak 的真值 提供五千余条中位搏与向量合成导联上的界标 先用 §5.4 的读取流程复现 §4.3 的案例,再全量评测
你在搭药物心脏安全性的在体替代模型 提供同一批人的五期交叉数据,可做自身对照 按受试者分组,用给药前时点做基線,算逐时点 ΔΔQTc
你怀疑自家 QTc 算法对复极早期不敏感 四种机制的药正好构成一组梯度 分别算 J-Tpeakc 与 Tpeak-Tendc,看两者是否被拉开
你在做心电基础模型,想找小而干净的评测集 十二导联、1000 Hz、信号质量高 只做推理评测,不要拿它微调
你要教临床药理学生理解「QT 延长不等于风险」 同一人五条曲线的对照素材 用 §9.2 的流程导出五期叠加图
你在复现某篇药物心电论文 论文原始数据与测量表都在 先对齐版本号与列名,再比对数值

1.5 一句话判断

它不是用来训练模型的库,是用来给「QT 延长」这个笼统结论做解剖的库:同一批人、四种机制、十六个时点,把复极拆成早晚两段,让你看见总时长背后的方向差异。

1.6 不适合谁:四条边界

不适合拿来做规模训练。 二十二名受试者,按人划分后训练侧不足二十人。任何参数量超过万级的模型都会在几分钟内记住全部样本,验证损失随后一路上扬。

不适合拿来做信号质量研究。 片段是软件在十六个时点里挑出的最优三条,噪声与伪差在源头已被排除。用这样的数据训练质量分类器,学到的不是「什么样的信号不可用」,而是「Antares 偏好什么样的信号」。

不适合拿来做疾病诊断。 受试者是健康志愿者,标签是药物、剂量与给药期。数据里没有心肌梗死、没有束支阻滞、没有房颤,任何诊断类任务在这里都没有监督信号。

不适合拿来做结局预测。 没有随访、没有不良事件、没有心律失常发生时间。它以复极形态作为替代终点,替代终点与结局之间的距离,正是这类数据无法回答的部分。

§2 数据构成与规格

2.1 五个给药期撑起一个拉丁方

试验采用随机、双盲、五期交叉、安慰剂对照的设计。每名受试者依次接受五种处理,每期只给一次药,两次给药之间留七天洗脱。五个给药期意味着每人都当过五次自己的对照,人与人之间的差异(年龄、体型、基础复极时长)被完全消掉,剩下的差异才归因于药。

给药在空腹状态下完成,剂量按各药的临床常用量设定:雷诺嗪一千五百毫克、多非利特五百微克、维拉帕米一百二十毫克、硫酸奎尼丁四百毫克。四药的剂量单位不同,不能横向比较毫克数,只能比较同一人在不同处理下的变化幅度。

项目 官方页面所载
设计 随机、双盲、五期交叉、安慰剂对照
受试者 22 名健康志愿者
给药方式 每期清晨单次口服,空腹
洗脱期 每期之间 7 天
每期观察窗 24 小时连续心电
采集参数 500 Hz,幅度分辨率 2.5 μV
抽取时点 16 个名义时点
每点片段 3 份十秒十二导联
抽取前状态 仰卧静息 10 分钟
抽取工具 Antares(AMPS-LLC,纽约)
发布采样率 1000 Hz(由 500 Hz 上采样)
处理代码 药物 剂量 商品名与厂家(官方页面所载)
A 雷诺嗪 1500 mg Ranexa,Gilead,Foster City,CA
B 多非利特 500 μg Tikosyn,Pfizer,New York,NY
C 维拉帕米 120 mg 盐酸维拉帕米,Heritage Pharmaceuticals,Edison,NJ
D 硫酸奎尼丁 400 mg Watson Pharma,Corona,CA
E 安慰剂 — —

处理代码的字母顺序与标题里的药名顺序一致:雷诺嗪、多非利特、维拉帕米、奎尼丁。这一点在拼临床表时很关键,因为 ARMCD 列存的是字母序列而不是药名,只按字母猜药名容易错位。

2.2 字段与记录的完整字典

库的组织方式分三层:波形层、注释层、表格层。三层通过同一个 EGREFID 串起来,这个标识是一串三十六字符的 UUID,既出现在文件名里,也出现在临床表的两列里。

路径 内容 文件构成
raw/<RANDID>/<EGREFID> 十秒十二导联原始片段 .dat + .hea
medians/<RANDID>/<EGREFID> 由该片段导出的中位搏 .dat + .hea + .atr
RECORDS 全部记录名清单 纯文本
ANNOTATORS 注释角色声明 纯文本
SCR-002.Clinical.Data.csv 逐条心电的临床与测量表 CSV
SCR-002.Clinical.Data.Description.txt 上表的列说明 纯文本
SHA256SUMS.txt 全部文件的校验和 纯文本

RECORDS 一共一万零四百五十五行,正好是原始层五千二百三十二段加中位层五千二百二十三条。两层的命名完全相同,靠目录区分,所以任何读取脚本都必须显式带上 raw/ 或 medians/ 前缀,否则会读到另一层去。

临床表是这份数据里信息密度最高的部分。它把人口学、给药信息、药代动力学与心电测量压在一行里,一行对应一段十秒心电。列名与含义如下。

列名 含义 单位或取值
EGREFID 心电唯一标识,与文件名相同 UUID 字符串
RANDID 受试者随机号 整数,如 1001
SEX 性别 M 或 F
AGE 筛选时年龄 岁
HGHT 筛选时身高 厘米
WGHT 筛选时体重 千克
SYSBP 基线收缩压 mmHg
DIABP 基线舒张压 mmHg
RACE 种族 原始填写值
ETHNIC 族裔 原始填写值
ARMCD 处理序列 A/B/C/D/E 的组合
VISIT 访视代码 PERIOD-X-Dosing 形式
EXTRT 处理名 药名或安慰剂
EXDOS 剂量 数值
EXDOSU 剂量单位 mg 或 μg
TPT 名义时点(相对给药) 小时
BASELINE 是否基线 Y 或 N
PCTEST 药代检测项目 文本
PCSTRESN 测得浓度,基线期缺失 数值
PCSTRESU 浓度单位 文本
RR RR 间期 毫秒
PR PR 间期 毫秒
QT QT 间期 毫秒
QRS QRS 时限 毫秒
JTPEAK J 点到 T 波峰 毫秒
TPEAKTEND T 波峰到 T 波终点 毫秒
TPEAKTPEAKP 双峰 T 波的两峰间距 毫秒
ERD_30 早期复极时长的三成 毫秒
LRD_30 晚期复极时长的三成 毫秒
Twave_amplitude 向量合成导联上的 T 波振幅 微伏
Twave_asymmetry T 波不对称度 无量纲
Twave_flatness T 波平坦度 无量纲

表里有三十三列,但列名只有三十二个——EGREFID 在描述文件里出现了两次。按标准 CSV 读入时,第二列会被自动改名成 EGREFID.1,两列内容相同。这是拼表时最常见的一处磕绊:按位置取列会错位,按名字取列会拿到一个带后缀的副本。

TPEAKTPEAKP 只在 T 波存在第二个峰时才有意义,PCSTRESN 在基线期为缺失。这两列的稀疏是设计使然,不是采集失误:基线期本就没有给药,自然没有浓度;双峰 T 波只在部分人、部分药物下出现。

2.3 一条记录的完整解剖

一段记录由同名的两个文件构成。头文件是纯文本,第一行声明记录名、导联数、采样率与采样点数,其后每行一个导联。以 §4.3 的案例为例,原始层的头文件长这样。

00ed2097-cd14-4f03-ab33-853da5be5550 12 1000 10000
00ed2097-cd14-4f03-ab33-853da5be5550.dat 16 149792(-19192)/mV 0 0 0 -13169 0 I
00ed2097-cd14-4f03-ab33-853da5be5550.dat 16  40562.6(-22753)/mV 0 0 0 -12715 0 II
00ed2097-cd14-4f03-ab33-853da5be5550.dat 16  50900.2(-22428)/mV 0 0 0  29987 0 III
00ed2097-cd14-4f03-ab33-853da5be5550.dat 16  66154.2(22430)/mV  0 0 0 -25274 0 AVR
00ed2097-cd14-4f03-ab33-853da5be5550.dat 16 130741.1(22389)/mV  0 0 0   4210 0 AVL
00ed2097-cd14-4f03-ab33-853da5be5550.dat 16  45156.9(-22607)/mV 0 0 0  -2797 0 AVF
00ed2097-cd14-4f03-ab33-853da5be5550.dat 16  74896(18256)/mV    0 0 0  26491 0 V1
00ed2097-cd14-4f03-ab33-853da5be5550.dat 16  37582.2(-5990)/mV  0 0 0 -19744 0 V2
00ed2097-cd14-4f03-ab33-853da5be5550.dat 16  25826.2(-21629)/mV 0 0 0   4968 0 V3
00ed2097-cd14-4f03-ab33-853da5be5550.dat 16  24935.6(-24663)/mV 0 0 0  -4528 0 V4
00ed2097-cd14-4f03-ab33-853da5be5550.dat 16  30044.2(-23942)/mV 0 0 0    -36 0 V5
00ed2097-cd14-4f03-ab33-853da5be5550.dat 16  36534.6(-22720)/mV 0 0 0 -24036 0 V6

第一行的四个数字依次是记录名、导联数、采样率、采样点数。一万个采样点除以一千赫兹,正好十秒。每行导联描述里的十六是每样本位数,斜杠前是增益(每毫伏对应的整数单位),括号里是基线,再往后是初始值、校验和与导联名。

头文件字段 含义 本例取值
记录名 与文件同名的 UUID 00ed2097…
导联数 原始层 12,中位层 16 12
采样率 发布后统一 1000 Hz 1000
采样点数 每段总点数 10000
存储格式 每样本位数 16
增益 每毫伏的整数单位数 逐导联不同,约 2.5 万至 15 万
基线 零电平 0
ADC 零值 整数零点 0

增益逐导联差异很大,I 导联接近十五万单位每毫伏,V4 只有约两万五。这不是错误,而是各导联信号幅度不同、为充分利用十六位动态范围所做的配置。任何把十二导联直接拼成矩阵喂给模型的写法,都需要先按增益与基线还原成毫伏,否则幅度大的导联会主导梯度。

2.4 十六个时点与三份重复

时点的选取围绕各药的达峰时间。给药前半小时取一次基线,给药后从半小时开始密集采样,前四小时每半小时一次,之后逐渐稀疏,最后一针落在第二十四小时。密集段覆盖了大多数口服药的血浆浓度峰值区间。

序号 相对给药时间 性质
1 −0.5 h 给药前基线
2 0.5 h 吸收早期
3 1 h 吸收期
4 1.5 h 吸收期
5 2 h 接近达峰
6 2.5 h 达峰附近
7 3 h 达峰附近
8 3.5 h 峰后
9 4 h 峰后
10 5 h 分布期
11 6 h 分布期
12 7 h 分布期
13 8 h 分布后期
14 12 h 消除期
15 14 h 消除期
16 24 h 次日同时刻

每个时点取三份而不是一份,理由有三:心电的复极时长存在逐搏波动,三份取中位可以压低噪声;三份之间的一致性本身是质量指标;监管审评的惯例是每个时点读三份再取平均。这三份不是连续的三下心跳,而是三段独立的十秒记录,抽取时要求心率稳定。

三份乘以十六个时点,再乘五个给药期与二十二名受试者,理论上限是五千二百八十段。官方给出的是五千二百三十二段,差额四十八段。官方页面没有说明这四十八段缺在哪里,可能是某次抽取失败、某段质量不达标被弃用,也可能是受试者中途退出某个给药期。存在两个口径:理论上限五千二百八十,实际发布五千二百三十二,差额构成官方未说明。

2.5 与同类资源的字段差异

心电公开数据里,带复极间期测量的并不多。多数库只给波形和节律标签,间期要靠使用者自己测;少数给了间期,但只给 QT 一个总数。这份数据的特殊之处在于把复极拆开,并且逐条给出拆分后的数值。

资源类型 典型字段 缺什么
心律失常库 波形 + 逐搏类型标签 无复极间期,无给药信息
诊断分类库 波形 + 诊断文本 间期测量不逐条给出
QT 专用库 波形 + 逐搏界标 通常无药物激发、无浓度
可穿戴质量库 波形 + 质量分级 无临床测量,无药物
本库 波形 + 中位搏界标 + 间期 + 浓度 + 给药 无疾病标签,无结局

字段的丰富是有代价的:这张临床表里的间期不是人工逐条读出来的,而是算法测量后汇总的。用这些数值做训练标签,等于把某个算法的输出当成真值;用它们做评测基准,则需要先确认测量口径与自己的一致。

§3 定位:它测的是复极的分裂,不是心律

3.1 早段与晚段,两种不同的电生理含义

心室复极在时间上可以粗分两段。J 点到 T 波峰这一段,对应大部分心室肌细胞处于平台期,外向钾电流与内向钙、钠电流相互拉扯,净电流很小,时长对内向电流的变化极其敏感。T 波峰到 T 波终点这一段,对应不同层次心肌复极完成时间的离散,外层先复极、内层后复极,两者的时间差构成这一段的主体。

两段对药物的反应方向可以相反。单纯阻滞 hERG 会让动作电位时程整体延长,两段一起变长;再叠加钙通道阻滞,平台期内向电流被削掉,早期复极反而缩短,晚期的延长被部分掩盖,总 QT 的变化因此被低估。官方引用的论文正是用这个逻辑解释了为什么四种药在总 QT 上看起来相似,在分段指标上却分得开。

分段 起止 电生理对应 对药物的敏感方向
早期复极 J 点至 T 波峰 平台期净电流平衡 内向电流被抑制则缩短
晚期复极 T 波峰至 T 波终点 跨壁复极离散 hERG 阻滞则延长
全程 QRS 起点至 T 波终点 除极加复极总时长 两个方向叠加

3.2 六类界标与它们的测量链

中位搏的注释以向量合成导联为基准,官方列出六类界标:P 波起点、QRS 起点、QRS 终点、T 波峰、次级 T 波峰(若存在)、T 波终点。前三个界定除极与复极的分界,后三个界定复极内部的划分。有了这六个点,QT、J-Tpeak、Tpeak-Tend 都能直接算出来,不需要再拟合。

界标 位置 用途
P 起点 心房除极开始 算 PR 间期
QRS 起点 心室除极开始 QT 间期的左端
QRS 终点 心室除极结束,即 J 点 早期复极的左端
T 波峰 第一峰 早期与晚期的分界
次级 T 峰 第二峰(若存在) 双峰 T 波的形态描述
T 终点 复极结束 QT 与晚期复极的右端

标注是半自动的:算法先给出候选位置,再由人工核对修正。官方用了「semi-automatic」这个词,但没有公布修正的比例、参与人数与一致性指标。这一点在评估标注质量时必须记住——它是一个经过人工把关的算法输出,不是双人独立标注的共识。

3.3 向量合成导联为什么是必需的

十二导联各自看心脏的一个角度,同一个复极事件在不同导联上的投影幅度不同、极性可能相反。如果逐导联测 T 波终点,会得到十二个不一致的答案,取平均并不解决根本问题——某个导联上 T 波几乎平坦时,终点根本无从谈起。

解法是把三个正交分量合成一个向量幅值导联,也就是中位层头文件里的 VCGMAG。它是 vx、vy、vz 三个分量的平方和开方,代表心电向量在三维空间中的长度,与导联轴的角度无关。复极在任何方向上都有投影,向量幅值因此总有清晰的峰与终点。中位层的头文件有十六个信号,正是十二导联加这四项。

中位层信号 数量 作用
标准十二导联 12 保留各导联形态,便于逐导联对照
VCGMAG 1 向量幅值,界标测量的主基准
vx / vy / vz 3 正交分量,可重建空间向量轨迹

这也解释了一个使用上的细节:临床表里的 T 波振幅单位是微伏,且明确写在向量合成导联上,而不是某个具体导联。不同导联的 T 波振幅不可比,向量幅值才可以跨人、跨药比较。

3.4 与波形边界标注库的分工

库内另有一条走波形边界路线的数据(QT Database),它的做法是逐搏人工校订界标,覆盖多种心律失常与形态异常的人群,导联数少、记录长。两者经常被放在一起提,但回答的问题不同。

维度 波形边界库 本库
标注对象 每一次真实心搏 每条记录合成出的一个中位搏
人群 含多种病理形态 全部健康志愿者
激发 无,静息或动态监测 四种药物加安慰剂
强项 边界算法的通用真值 药物引起的边界位移
弱项 无浓度、无给药、无分段指标 无病理形态、无逐搏变异

如果你的目标是「把 T 波终点测准」,两者可以互补:用边界库调算法,用本库验证算法在复极形态被药物改变后是否还稳。如果目标是「证明某药改变了复极的哪一段」,只有本库能提供对照结构。

3.5 它不测什么

这份数据不含心律标签,也不含任何心律失常事件。它记录的是窦性心律在药物作用下的形态变化,中位搏合成时还专门剔除了非窦性搏。想研究早搏、房颤、传导阻滞,这里没有素材。

它也不测长时程趋势。虽然每期连续记录了二十四小时,但发布包里只有十六个时点的十秒切片。想看复极在一天中的昼夜节律、想看给药后两小时到三小时之间的连续演变,得回到未发布的原始连续记录——那份数据不在公开范围内。

常被以为有 实际情况
连续 24 小时波形 发布包只有 16 个时点的十秒切片
心律事件标签 无,中位搏合成时已剔除异位搏
信号质量分级 无,且片段已被择优
不良事件与随访 无
多中心数据 单一临床药理单元

§4 质量与特色:三份十秒怎么挑出「最优」

4.1 择优抽取带来的系统性偏置

官方对抽取流程的描述只有一句:在每个时点用 Antares 软件挑出三份心率稳定、信号质量最优的十秒片段。这句话里藏着一个对下游影响极大的事实——发布出来的片段不是随机样本,而是经过质量筛选的样本。

这意味着两件事。其一,任何在真实场景中会遇到的基线漂移、肌电干扰、电极脱落,在这份数据里都被大幅稀释,用它评估算法的噪声鲁棒性会得到过于乐观的结论。其二,如果某个算法的失败模式恰好发生在低信噪比区间,这份数据根本触发不了它,评测结果会虚高。反过来说,这也是它的优点:要做复极形态的精测,本来就需要干净的信号。

抽取要求 官方表述 对数据的影响
心率稳定 stable heart rates 排除心率骤变段,RR 序列偏平滑
信号质量最优 maximum signal quality 噪声与伪差被系统性剔除
时长固定 10-second 每段 10000 点,可直接堆成张量
体位固定 仰卧静息 10 分钟 减少体位导致的电轴漂移
每点三份 triplicate 可算段间一致性,也可取中位

4.2 中位搏是怎么合成的

中位搏不是随便挑一个好看的心跳,而是把十秒内所有窦性搏按 QRS 逐样本对齐,再对每个采样位置取中位数。取中位而不是均值,是为了压低残余噪声与偶发伪差的影響——均值会被一个离群的采样点拉偏,中位数不会。

对齐之前要先剔除异位搏。官方说用的是互相关系数与 RR 间期历史两个判据:形态与模板相关性低的心搏被剔除,RR 间期明显偏离历史节律的心搏也被剔除。这一步保证了合成出来的波形代表的是稳定窦律,而不是几种形态的平均。

步骤 做法 目的
心搏检测 在十秒段内定位 QRS 建立对齐锚点
异位剔除 互相关系数 + RR 间期历史 只保留窦性搏
逐样本对齐 以 QRS 为基准对齐 消除时间抖动
取中位数 每个采样位置取中位 压低噪声,抵抗离群
生成新记录 输出 16 通道、约 1.16 秒 供界标标注与测量

合成后的波形长度约一千一百六十个采样点,也就是一点一六秒左右,足够覆盖一次完整的心动周期。它的采样率与原始层相同,都是一千赫兹,但通道数多了四个——十二导联之外加了向量幅值与三个正交分量。

4.3 案例:记录 00ed2097 的一条十秒段

取受试者 1001 名下的这段记录做解剖。它是原始层的一段十秒十二导联,文件名是一串 UUID,头文件里有十二个导联、一千赫兹、一万个采样点。三个数字互相印证:一万除以一千等于十秒,与官方声明的片段长度一致。

在它的中位层版本里,头文件变成十六个信号、一千一百五十九个采样点。多出来的四个通道是 VCGMAG、vx、vy、vz;长度从一万降到一千一百五十九,因为中位搏只保留一个心动周期。同一段记录在两层里的采样率相同、增益各自独立,不能把两层的数据直接拼接。

它的注释文件只有五个点:采样点 164、297 处是起点符号,392、674 处是终点符号,597 处是 T 波峰符号。也就是说,官方列出的六类界标里,这一段实际只有四个界标加一个峰——P 起点、QRS 起点、QRS 终点、T 峰、T 终点,次级 T 峰不存在。官方没有公布符号对照表,这五个点的归属需要结合波形自行确认。

项目 原始层 中位层
路径 raw/1001/00ed2097… medians/1001/00ed2097…
信号数 12 16
采样点数 10000 1159
时长 10 秒 约 1.16 秒
注释 无 5 个点
用途 形态与算法输入 界标真值与间期测量

这段记录值得反复回看:它同时展示了三层结构(波形、注释、表格)如何在一个 UUID 上会合,以及「六类界标」在具体记录上可能只剩五个点。官方描述的是能力上限,不是每条记录的实际情况。

4.4 五千二百三十二与五千二百二十三之间的九个缺口

原始层有 5,232 段,中位层只有 5,223 条。九个原始片段没有对应的中位搏。官方只说了「为其五千二百二十三条导出了中位搏」,没有解释这九条为什么缺席。

合理的技术解释有几种:某个片段里检测不到足够多的窦性搏,无法合成稳定中位;某个片段全程伪差,剔除异位搏后剩余心搏太少;某段的 QRS 对齐失败。官方没有说明,任何具体归因都是推测。

层 数量 说明
原始片段 五千二百三十二段 每段十秒、十二导联
中位搏 五千二百二十三条 附 .atr 注释
差额 9 段 官方未说明原因
清单总行数 10,455 行 两层之和

这个缺口在使用时要显式处理。按 RECORDS 遍历、在两层都尝试读取的脚本,会在中位层遇到九次文件不存在;先读中位层再回查原始层的脚本,则会静默丢掉九段。两种写法都能跑通,但统计口径不同,写论文时必须说清用的是哪一层。

4.5 它没有的东西,比它有的更需要记住

缺失项 后果 替代方案
连续 24 小时波形 无法做昼夜节律与动态趋势 只能用 16 个时点做粗粒度曲线
原始段上的逐搏标注 无法直接做逐搏间期统计 自行检测 R 峰,或改用中位搏
信号质量标签 无法做质量分类 换用带质量标注的可穿戴库
疾病与用药史 无法做混杂校正 只有年龄、性别、身高、体重、血压
不良事件与随访 无法做结局建模 只能停在替代终点
研究中心信息 无法做中心效应分析 官方页面未公布中心数量

§5 取数:从 1.4 GB 到一张分析表

5.1 目录与环境

整库解压后 1.4 GB,其中绝大部分是原始层的二进制波形。临床表只有 1.2 MB,清单一类都是几十到几百 KB。这意味着一个常见的取数策略是可行的:只拉表格与清单,先把分析框架搭好,再按需拉波形。

文件或目录 体积 是否必需
raw/ 约 1.3 GB 做形态与算法时必需
medians/ 约 60 MB 做界标与间期时必需
SCR-002.Clinical.Data.csv 1.2 MB 必需
RECORDS 490.1 KB 必需
SHA256SUMS.txt 2.9 MB 校验时用
ANNOTATORS 29 B 说明注释角色

5.2 两种下载方式

官方给了三条路径:网页打包下载、wget 递归、S3 同步。前两条走 PhysioNet 的常规带宽,第三条走开放存储桶,通常更快,且支持断点续传。

#-- 方式一:只取元数据,先搭框架
BASE=https://physionet.org/files/ecgrdvq/1.0.0
mkdir -p ecgrdvq_meta
curl -sL "$BASE/RECORDS" -o ecgrdvq_meta/RECORDS
curl -sL "$BASE/ANNOTATORS" -o ecgrdvq_meta/ANNOTATORS
curl -sL "$BASE/SCR-002.Clinical.Data.csv" -o ecgrdvq_meta/clinical.csv
curl -sL "$BASE/SCR-002.Clinical.Data.Description.txt" -o ecgrdvq_meta/columns.txt

#-- 方式二:全量同步(S3 开放桶,无需凭证)
aws s3 sync --no-sign-request s3://physionet-open/ecgrdvq/1.0.0/ ecgrdvq_full/

#-- 方式三:递归抓取,只补缺失文件
wget -r -N -c -np "$BASE/" -P ecgrdvq_full

全量下载后建议先校验。SHA256SUMS.txt 覆盖了全部文件,逐行比对可以发现下载中断造成的半截文件——这类文件往往头文件完整、.dat 只有前几兆,读取时才会报长度不符。

#-- 在解压目录内执行,输出仅列出校验失败的行
sha256sum -c SHA256SUMS.txt 2>&1 | grep -v ': OK$' | head -20

5.3 读一段原始波形

WFDB 的 Python 包能直接按项目名远程读取,不必先下全量。读进来的是物理量(毫伏),增益与基线已经处理过。

import wfdb
import numpy as np

#-- 远程读取单个原始片段;pn_dir 指向 PhysioNet 项目目录
rec = wfdb.rdrecord(
    "raw/1001/00ed2097-cd14-4f03-ab33-853da5be5550",
    pn_dir="ecgrdvq",
)

print(rec.fs)              #-- 1000
print(rec.sig_len)         #-- 10000
print(rec.sig_name)        #-- 十二导联名
print(rec.p_signal.shape)  #-- (10000, 12)
print(rec.units)           #-- 逐导联单位,通常为 mV

#-- 取 II 导联十秒的中位数幅度,用于快速确认信号非空
lead_ii = rec.p_signal[:, rec.sig_name.index("II")]
print(np.median(lead_ii), lead_ii.min(), lead_ii.max())

如果想读整数原始值而不是毫伏,用 wfdb.rdrecord(..., physical=False),得到的是 d_signal。做位深分析或复现厂商算法时用整数,做形态测量时用毫伏。

5.4 读中位搏与注释

中位层多一个 .atr,读取时要同时取波形与注释。注释里的采样点是相对中位搏起点的偏移,单位是采样点,除以采样率才是毫秒。

import wfdb

name = "medians/1001/00ed2097-cd14-4f03-ab33-853da5be5550"

#-- 中位层有 16 个信号:12 导联 + VCGMAG + vx/vy/vz
mrec = wfdb.rdrecord(name, pn_dir="ecgrdvq")
print(mrec.sig_name)       #-- 末尾四项为 VCGMAG、vx、vy、vz
print(mrec.sig_len)        #-- 1159

ann = wfdb.rdann(name, "atr", pn_dir="ecgrdvq")
marks = list(zip(ann.symbol, ann.sample))
print(marks)               #-- 本段为 5 个点:起点、起点、终点、T 峰、终点

#-- 官方没有公布符号对照表,只能按本段实际出现的符号分组
starts = [s for s, sym in marks if sym == "("]
ends   = [s for s, sym in marks if sym == ")"]
tpeaks = [s for s, sym in marks if sym == "t"]

fs = 1000
jt_peak   = (tpeaks[0] - ends[0]) / fs * 1000
tpeak_tnd = (ends[-1] - tpeaks[0]) / fs * 1000
print(f"J-Tpeak {jt_peak:.0f} ms, Tpeak-Tend {tpeak_tnd:.0f} ms")

在 §4.3 的案例上,这段代码给出 J-Tpeak 与 Tpeak-Tend 两个数,与临床表里同一 EGREFID 的 JTPEAK、TPEAKTEND 列应当对得上。对不上就说明符号归属判断错了——这是自检符号约定最省事的办法。注意 ends[0] 是 QRS 终点、ends[-1] 是 T 终点,两者的次序一旦反了,晚期复极会算成负数。

5.5 把三层合成一张表

临床表以 EGREFID 为主键,波形文件以 UUID 为文件名,两者是同一个字符串。拼表的关键是把路径里的 UUID 抽出来当列,再去 join。

---- 用 DuckDB 直接把清单与临床表拼起来,无需先解压波形
CREATE TABLE cli AS
SELECT * FROM read_csv_auto('ecgrdvq_meta/clinical.csv', header = true);

---- RECORDS 每行是 raw/<RANDID>/<UUID> 的形式,切出层、受试者与 UUID
CREATE TABLE recs AS
SELECT
    split_part(column0, '/', 1) AS layer,
    split_part(column0, '/', 2) AS randid,
    split_part(column0, '/', 3) AS egrefid,
    column0                     AS path
FROM read_csv('ecgrdvq_meta/RECORDS', header = false, delim = '\t');

---- 按 UUID 关联,检查每一层各能配上多少行
SELECT layer, count(*) AS n, count(cli.EGREFID) AS matched
FROM recs LEFT JOIN cli ON recs.egrefid = cli.EGREFID
GROUP BY layer ORDER BY layer;

查询结果会显示原始层与中位层的差异,以及临床表是否覆盖了全部片段。如果 matched 明显小于 n,先检查 UUID 是否被当成了带引号的字符串,再检查 CSV 是否有 BOM。

5.6 按受试者与给药期划分

同一名受试者在五个给药期里出现,同一期内还有十六个时点、每个时点三份。任何随机切分都会把同一人的数据同时放进训练与测试,指标会虚高。正确的做法是先按 RANDID 分组,再在组内保留完整的期与时点结构。

import pandas as pd

cli = pd.read_csv("ecgrdvq_meta/clinical.csv")
cli.columns = [c.strip().lstrip("\ufeff") for c in cli.columns]

#-- 表头里 EGREFID 出现两次,去重保留第一列
cli = cli.loc[:, ~cli.columns.duplicated()]

#-- 受试者随机号是划分单位,不是片段
subjects = sorted(cli["RANDID"].unique())
cut = int(len(subjects) * 0.7)
train_ids, test_ids = subjects[:cut], subjects[cut:]

train = cli[cli["RANDID"].isin(train_ids)]
test  = cli[cli["RANDID"].isin(test_ids)]
print(len(train_ids), len(test_ids), train.shape, test.shape)

二十二人按七三切,测试侧只有六人。这个数量做点估计可以,做置信区间会很宽。更稳的做法是留一法交叉验证:每次留一个人,二十二折,报告每折的误差与总体均值。

§6 与库内其他心电数据的关系

6.1 关系图谱

在心电数据的版图上,这份数据站在「药物激发」这条很窄的支线上。它与诊断库、节律库、质量库都不重叠,但和另外两类数据有真实的接口:波形边界标注库提供通用真值,药物安全性库提供更大规模的同类证据。

库内词条 定位 与本库的关系 能否互换
BUT QDB 单导联长时程,逐点质量分级 任务正交,一个测可用性,一个测复极 不能,标签体系完全不同
CiPA 心电验证研究 六十人、七个给药组的药物心电 同源问题,规模更大、设计更晚 不能直接互换,但可互为外部验证
QT Database 双导联、逐搏人工界标 标注粒度更细,人群更杂 可互补,本库胜在有药物激发
INCART 十二导联半小时、逐搏类型 时长与导联数都不同 不能,任务无交集
PTB-XL 系列 大规模十二导联临床诊断 规模差两个数量级 不能,本库无诊断标签
MIT-BIH 心律失常库 双导联、逐搏类型 无复极测量 不能
可穿戴心电库 单导联、自由生活 场景相反,本库是卧床静息 不能

一个容易忽略的接口是与 QT 测量算法生态的关系。多数 QTc 算法在临床数据上验证,验证集里的复极形态是自然的;本库提供的是被药物系统性改变过的复极形态,正好用来测算法在边界情形下的稳定性。这类用法不需要标签,只需要同一段波形上「算法给的 T 终点」与「官方给的 T 终点」的差。

6.2 与 BUT QDB 的区隔:一个问能不能用,一个问变成什么样

两者都以「心电」开头,都在 PhysioNet 上,都免注册,很容易被搜到一起。它们的关系可以用一句话钉死:BUT QDB 回答「这段信号值不值得分析」,本库回答「这段信号在药物作用下发生了什么变化」。

维度 ECGRDVQ BUT QDB
数据来源 单中心五期交叉临床试验 自由生活状态下的可穿戴佩戴
受试者 22 名健康志愿者 15 名志愿者,18 条记录
导联 十二导联,卧床静息 单导联贴片,日常活动
时长 每段 10 秒,共 16 个时点 每条不少于 24 小时连续
采样 采集 500 Hz,发布 1000 Hz 1000 Hz
标注对象 中位搏上的复极界标 逐采样点的三档质量
标注者 半自动算法加人工核对 三名专家独立标注后合成共识
标签体系 药物、剂量、时点、间期测量 可用 / 不可用 / 不确定
核心用途 复极分段与药物机制验证 质量评估算法的训练与评测
许可 ODC-BY 1.0 CC BY 4.0

三条差异最值得记住。第一,标注对象完全不同:一个是波形上的时间点,一个是时间轴上的区间;前者服务于测量,后者服务于筛选。第二,信号质量的方向相反:本库的片段由软件择优挑选,整体偏干净;BUT QDB 刻意保留真实佩戴中的糟糕段落,噪声本身就是被标注的对象。第三,人群状态相反:本库是被固定在床上的静息仰卧,BUT QDB 是走动、运动、睡觉的自由生活。

因此两者不存在替代关系,只存在串联关系。真实的远程心电筛查流水线里,质量模型在前(BUT QDB 那类数据训练),复极或形态分析在后(本库那类数据验证)。把本库当质量库用,会因为样本已被筛选而得到虚高的准确率;把质量库当复极库用,则会因为单导联、长时程、无给药而根本无法做分段测量。

两者的区隔还有一个常被忽略的层面:标注成本。质量标注是逐采样点的区间标注,一条二十四小时记录的工作量以小时计;复极界标是每条中位搏五个点,一条记录几分钟。这决定了两类数据不可能由同一批人、以同一种节奏生产,也决定了它们的规模上限完全不同。

6.3 与 CiPA 的区隔:真正的近邻

库内还有一条更近的记录——CiPA 心电验证研究。它同样由 FDA 主导,同样是十二导联十秒片段、同样带血药浓度、同样关注 J-Tpeakc。两者放在一起,才看得出本库的位置。

维度 ECGRDVQ CiPA 心电验证研究
受试者规模 22 人 60 人(据库内对应词条)
给药组 4 药 + 安慰剂,5 期 7 个给药组
心电条数 五千二百余段 五千七百余段(据库内对应词条)
年代 2013 年前后试验,2016 年发布 更晚,服务 CiPA 计划
主要目的 证明复极可被分段区分 为三层评价体系提供临床层证据
与本库的关系 前身与概念验证 规模更大的后续验证

两者的差别不在设计思想,而在证据强度。本库是「这个想法行得通」的证明,CiPA 是「这个想法在一批更大的样本、更多药物上仍然行得通」的验证。做方法学研究时,本库更适合当开发集(结构简单、时点规整),CiPA 更适合当确认集(规模更大、药物谱更广)。反过来用也行,但要在论文里说明为什么。

6.4 检索路径

按用途反查,路径大致如下。

你的目标 先看哪个库 理由
复极界标与间期算法 本库 唯一同时给 J-Tpeak 与 Tpeak-Tend 的公开集之一
药物浓度-效应建模 本库 → CiPA 先在小样本上定型,再到大样本上确认
通用波形边界真值 QT Database 逐搏人工标注,人群更杂
信号质量评估 BUT QDB 逐点三档标签,噪声未被筛掉
心律失常分类 MIT-BIH、INCART 有逐搏类型,样本量合适
临床诊断分类 PTB-XL 系列 有诊断超类,规模大

检索时注意两个命名陷阱。搜「RDVQ」只会命中本库,因为这是四个药名的缩写,不是通用术语;搜「QT」会同时命中 QT Database、长 QT 相关研究与大量 QTc 算法论文,需要加上 drug-induced 或 J-Tpeak 才能收窄。

§7 质量评估与局限性

7.0 阅读本节前的一个前置校正

先纠正一个常见的误判:把「人少」直接等同于「质量低」。这份数据的二十二个人不是抽样不足,而是交叉设计的前提——每个人要在五个月里反复来五次、每次躺二十四小时,能完成这套流程的志愿者本来就不多。

统计效能来自重复测量:每人在每期贡献四十八条片段,五期两百四十条,二十二人合计五千余条。做浓度-效应曲线时,每条曲线内部有十六个时点、每点三份重复,这个密度足以拟合个体化的斜率。真正受限的不是总条数,而是「独立个体数」——凡是需要跨人推断的结论(比如人群平均效应),二十二这个数字就是硬上限。

把这两件事分开看,五维评分的读法才正确:规模一项分数低,是因为独立个体少;任务适配一项分数高,是因为结构不可替代。混在一起看,会得出「不值得用」的错误结论。

7.1 五维评分

按 DAIMS 的常用维度打分,每项 1–5 分,针对「作为药物复极研究数据」这一用途。

维度 分数 理由
数据规模 2 二十二名受试者,独立个体少;片段数够但不独立
标注质量 3 半自动标注,无一致性指标,六类界标常缺项
任务适配 5 药物激发加分段指标,公开数据里几乎没有替代
文档完整 4 页面与列说明清楚,但符号表、缺失原因未交代
可获取性 5 免注册、ODC-BY、单包可下

合计十九分(满分二十五)。分数结构与 INCART 那类小库相似:规模拖后腿,适配性拉满,标注质量处于中位——比纯算法输出可信,比双人独立标注弱。

7.2 标注质量的两层

第一层是界标位置准不准。官方说标注是半自动的,意味着有人工核对环节,但没说是几人、核对了多少、有没有一致性统计。对照 §4.3 的案例,一条中位搏只有五个点,说明「六类界标」是能力上限而非逐条保证。次级 T 峰在多数记录里并不存在,缺项是常态。

第二层是间期数值可不可信。临床表里的 QT、JTPEAK 等列是算法测量的汇总,不是界标的手工复算。理论上界标与间期应当自洽,但两者可能来自不同的测量环节。使用时最稳妥的做法是:拿界标自己算一遍间期,与表里的数值对照,一致则用表,不一致则以界标为准并记录差异。

用途 标注精度的影响 建议
界标检测算法评测 大,直接决定真值 先剔除只有四个点的记录,再评测
间期回归 中,取决于用表还是用界标 用界标自算,表只做交叉核对
复极形态分类 小,形态本身不依赖精确终点 可直接用中位搏波形
浓度-效应建模 中,误差会进入斜率 用混合效应模型吸收个体差异

7.3 已知的、可枚举的偏差

偏差 表现 影响
健康志愿者偏斜 全部为筛选合格的成年人 无病理形态,无合并用药
单中心 一家临床药理单元完成全部给药与记录 设备、电极、操作习惯单一
择优抽取 每点只留最好的三份 信噪比虚高,噪声任务失效
单次给药 每期只给一剂 无稳态浓度,无蓄积效应
剂量固定 每药一个剂量水平 无法拟合剂量-反应,只能做浓度-反应
中位搏合成 剔除异位搏后取中位 逐搏变异被抹平,心律失常不可见
缺项界标 次级 T 峰常不存在 六类界标实际常为五类
无结局 无不良事件与随访 只能做替代终点

还有一类偏差不来自数据本身,而来自它的名气。因为出自监管机构团队、发表在临床药理顶刊,它常被当成「药物心电的权威基准」。这是一种身份溢出:它在证明「复极可以分段」这件事上是权威的,在「某药是否安全」这件事上不是。把前者的话语权挪到后者,是最常见的误用。

7.4 外部验证矩阵

这份数据在文献里的角色,大致可以分成四种。它们讲得通的地方与风险各不相同。

验证角色 做法 讲得通的地方 风险
算法真值 用中位搏界标评测 T 终点检测 有官方界标,可复现 半自动标注本身有误差,会把算法误差与标注误差混在一起
机制复现 复算四种药的 J-Tpeak 与 Tpeak-Tend 变化 原始数据与测量表齐全 剂量与人群固定,结论不能外推
浓度-效应 用 PCSTRESN 拟合暴露-反应 每点有浓度,三份重复 每点仅一个血样,个体内浓度曲线稀疏
跨库泛化 在别的库训练,在本库测试 人群干净、设备不同 本库无病理标签,只能测间期类任务

外部验证的一个具体做法是「同库自证」:用临床表里的间期当标签训练一个回归模型,再用界标自算的间期当测试。如果模型在测试上掉得厉害,说明表里的数值与界标之间存在系统性口径差,这个差本身就是有价值的信息——它告诉你厂商算法与官方标注在哪个环节分歧最大。

反过来也要防止把自证结果当成泛化能力。同一批人、同一台设备、同一套抽取流程,训练与测试之间的相关性极高。任何在这份数据内部达到的高分,都需要另一份数据来确认。

7.5 它为何能持续:因为「四种机制同批人」这个组合没人再复制

它没有扩版,没有第二版,十年过去仍是五千余段。原因不在技术,在成本:要让同一批人依次吃四种已知延长 QT 的药,还要在每期躺满二十四小时、抽十六次血,这在今天的伦理与商业环境下几乎不可能重做。后来者选择了另一条路——扩大人数、增加给药组(CiPA 就是这样做的),而不是在同一个人身上做五次完整对照。

这个组合的稀缺性决定了它的寿命。只要药物心脏安全性评价还需要「复极可以分段」这个前提的原始证据,这份数据就会被引用;只要没有第二个团队愿意重做五期交叉,它就没有替代品。它的价值不在数量,在于它是那个实验设计的唯一公开留档。

§8 生态位与历史

8.1 从监管科学里长出来的一条数据线

这份数据的作者群分布很说明问题:一部分来自美国 FDA 的器械与放射健康中心、药物评价与研究中心,一部分来自威斯康星州的一家临床药理研究机构,还有一部分来自做药代检测的实验室。三方分工清楚——监管方提问题与定方法,临床方执行给药与记录,实验室做浓度测定。

这种组合在公开数据集里不常见。多数医学数据来自医院信息系统或科研项目,问题是「临床上发生了什么」;这一份的问题是「监管审评需要什么证据」。前者产出观察性数据,后者产出实验性数据。实验性数据的优点是因果清晰,缺点是场景人为。

8.2 与 QT 之争的关系

过去二十年,药物心脏安全性评价经历过一次范式转移:从「看 QT 延长多少」转向「看多通道阻滞的净效应」。促成这次转移的关键证据之一,就是「单纯 hERG 阻滞与多通道阻滞在总 QT 上可能看不出差别」这个观察。要证明它,必须有同一批人在不同机制药物下的对照数据。

这份数据提供的正是这个对照。它让「QT 延长」从终点降级为中间变量,把 J-Tpeak 与 Tpeak-Tend 推到了前台。今天讨论药物致心律失常风险时绕不开的「平衡型阻滞」概念,其经验基础里就有这批记录。

阶段 主流指标 本库的位置
2005 年前 QT 延长幅度 前史,尚未出现
2005–2013 全面 QT 研究(TQT) 试验设计与本库同期
2013–2017 QTc 加形态学 本库发表,提供分段证据
2017 年后 多通道 + 浓度-反应 成为方法学基准之一

8.3 与临床心电库的距离

把它和临床心电库放在一起,会看到两种完全不同的数据生产逻辑。临床库追求覆盖:更多病种、更多人群、更长时间、更多中心,因为下游任务是不可预知的。本库追求控制:固定人数、固定剂量、固定时点、固定体位,因为下游问题是明确的。

维度 临床心电库 本库
生产逻辑 覆盖优先 控制优先
人群 患者,异质 健康志愿者,同质
时间结构 自然发生 人为设定
标签来源 病历与判读 试验方案与测量
可外推范围 宽但弱 窄但强

这个对比解释了一个常见困惑:为什么它的条数不少,却几乎没人在里面做深度学习。因为深度学习的收益来自异质性与规模,而这两点恰恰是被设计刻意压掉的。

8.4 生态位总结

它占的坑是「药物激发下的复极分段」。这个坑很窄,但下面垫着三样东西:监管科学的问题意识、交叉试验的因果结构、半自动标注的可复现性。三者缺一,这个坑就不成立。

角色 它是不是 说明
训练集 不是 人少、标签是药不是病
评测集 是 界标与间期可作真值
机制证据 是 四种机制同批人对照
教学素材 是 一人五曲线,直观
临床基准 不是 健康人、单剂量、无结局

§9 使用指引

9.1 三种角色的路径

角色 第一天 第一周 注意事项
算法研究者 跑通 §5.3 与 §5.4,复现 §4.3 的案例 全量评测 T 终点检测,按人做留一交叉 先定界标符号约定,再谈精度
药物安全评价 拉临床表,画五人五药的复极曲线 拟合浓度-效应,比较 J-Tpeakc 与 Tpeak-Tendc 剂量不可横向比较,只比同人变化
教学与临床工程 取同一人五期片段做叠加图 讲清「总 QT 相同、分段不同」 说明这是健康志愿者单次给药

9.2 一条最短的可用流程

从零到一张能看的图,最短路径是:取表、按人分组、算相对基线的变化、画五条曲线。

import pandas as pd
import numpy as np

cli = pd.read_csv("ecgrdvq_meta/clinical.csv")
cli.columns = [c.strip().lstrip("\ufeff") for c in cli.columns]
cli = cli.loc[:, ~cli.columns.duplicated()]
cli["TPT"] = pd.to_numeric(cli["TPT"], errors="coerce")

#-- 心率校正常用 Fridericia:QTc = QT / RR^(1/3),RR 以秒计
rr_s = cli["RR"] / 1000.0
cli["QTcF"] = cli["QT"] / np.cbrt(rr_s)

#-- 同一受试者、同一给药期内的给药前时点作为该期基线
base = (cli[cli["BASELINE"] == "Y"]
        .groupby(["RANDID", "VISIT"])["QTcF"]
        .mean()
        .rename("QTcF_base")
        .reset_index())
cli = cli.merge(base, on=["RANDID", "VISIT"], how="left")
cli["dQTcF"] = cli["QTcF"] - cli["QTcF_base"]

curve = (cli.groupby(["EXTRT", "TPT"])["dQTcF"]
         .agg(["mean", "std", "count"])
         .reset_index()
         .sort_values(["EXTRT", "TPT"]))
print(curve.head(10))

画图时把五条曲线叠在一张坐标里,横轴是相对给药时间,纵轴是相对基线的 QTcF 变化。安慰剂那条线是参照,四条药线的分离程度与分离时刻,就是这个试验最想展示的东西。

9.3 引用方式

引用对象 内容
数据集 ECG Effects of Ranolazine, Dofetilide, Verapamil, and Quinidine, v1.0.0. PhysioNet. 2016. DOI 10.13026/C2HP45
方法论文 Johannesen L, Vicente J, Mason JW, et al. Clin Pharmacol Ther. 2014. doi:10.1038/clpt.2014.155
形态学论文 Vicente J, Johannesen L, Mason JW, et al. J Am Heart Assoc. 2015. doi:10.1161/JAHA.114.001615
平台 PhysioNet 平台综述(2026,Nature Health),按官方页面 Cite 按钮生成
注册号 ClinicalTrials.gov NCT01873950

写论文时建议同时注明三点:用的是原始层还是中位层、界标是自己从 .atr 读的还是直接取临床表的列、间期用的是哪一套心率校正公式。这三点不写清,别人无法复现你的数值。

§10 AI 使用声明

项目 声明
文本生成 本文由 AI 辅助撰写,编辑负责结构与事实核对
数字来源 规模、结构、边界三类数字取自 PhysioNet 官方页面与官方文件
文件核验 页面、.hea 头文件、RECORDS、ANNOTATORS、列说明文件经直接访问确认
论文信息 仅参考 Europe PMC 摘要与作者单位,未读全文
标注细节 符号与点位数取自一条记录,官方未公布符号表
未核验内容 缺失九条中位搏的原因、标注一致性指标、研究中心数量
图像 无配图;封面为生成式提示词,不含真实心电图
免责 不构成临床或监管建议;使用须遵守 ODC-BY 1.0 署名要求

常见误读(避坑清单)

说法 实际 证据
「RDVQ 是某种心电质量评分」 是四个药名的首字母:Ranolazine、Dofetilide、Verapamil、Quinidine 官方标题全称
「它是二十二个人的小样本,没什么用」 交叉设计,每人五期自身对照,片段数五千余 官方摘要与设计描述
「它有连续二十四小时波形」 只发布十六个时点的十秒切片 目录只有 raw 与 medians 两层
「原始片段带逐搏注释」 注释只在 medians 层,对象是中位搏 只有 medians 下有 .atr
「它能用来做心电质量评估」 片段由软件择优挑选,噪声已被排除 官方抽取描述
「六类界标每条都有」 常见只有五个点,次级 T 峰常缺 §4.3 的案例
「临床表列名唯一」 EGREFID 出现两次,读入后变 EGREFID.1 列说明文件
「文件按 randid/egrefid.ecg 存放」 实际是 .dat 加 .hea,按 UUID 命名 列说明与实际目录不一致
「采样率是 500 Hz」 采集 500 Hz,发布时上采样到 1000 Hz 头文件第二字段为 1000
「可以按片段随机划分训练测试」 同一人跨五期,必须按人划分 RANDID 列

FAQ

Q1:ECGRDVQ 到底是不是心电质量库?
不是。全称是四种药的心电效应,缩写取四个药名首字母。数据里没有任何质量标签,片段反而是软件挑出来的最优三条。质量方向请看 BUT QDB。

Q2:为什么只有二十二个人?
因为它是五期交叉设计,每人要完成五次二十四小时给药观察。人数少是设计代价,统计效能来自重复测量与自身对照,而不是人群广度。

Q3:五千二百三十二段是怎么来的?
十六个时点、每点三份、五个给药期、二十二名受试者,理论上限五千二百八十段,实际发布五千二百三十二段,差额四十八段官方未说明。

Q4:中位搏和原始片段有什么区别?
原始片段是十秒真实波形,十二导联;中位搏是把十秒内的窦性搏对齐后逐点取中位得到的单周期合成波形,十六通道,附界标注释。前者用于算法输入,后者用于测量真值。

Q5:J-Tpeak 和 Tpeak-Tend 分别代表什么?
J-Tpeak 覆盖复极早期,反映平台期净电流平衡;Tpeak-Tend 覆盖晚期,常作跨壁复极离散的代理。纯 hERG 阻滞两段都延长,叠加钙或晚钠阻滞会优先缩短早期。

Q6:能用它训练 QTc 预测模型吗?
可以训练,但只能在二十二人的范围内做留一验证,且标签是算法测量值而非临床判读。它的合理定位是评测集,不是训练集。

Q7:临床表里的间期是人工测的还是算法测的?
官方没有明说,只说是测量的汇总。稳妥做法是用 .atr 界标自己算一遍,与表里的数值对照,一致则采信,不一致则以界标为准并记录差异。

Q8:为什么注释符号没有对照表?
官方只列出六类界标的名称,没有给出 WFDB 符号与界标的映射。实际使用时需要结合波形与点位顺序自行确认,并用临床表的间期数值做交叉验证。

Q9:它能和 CiPA 数据混用吗?
可以互为开发集与确认集,但不要直接拼接训练——两套试验的人数、给药组、时点密度都不同,混在一起会引入批次效应。分开建模、交叉验证更稳妥。

Q10:许可允许商用吗?
ODC-BY 1.0 允许包括商业用途在内的使用,条件是署名。引用时写清数据集名称、版本、DOI 与访问日期。

Q11:为什么没有连续二十四小时波形?
试验期间确实连续记录了二十四小时,但发布包里只有按十六个时点抽取的十秒片段。连续记录是否可得,官方页面没有说明。

Q12:缺的九条中位搏会影响结论吗?
影响很小,九条相对五千余条不到千分之二。但按层统计时必须显式处理,否则两层行数对不上,join 之后会静默丢样本。

术语表

术语 解释
交叉试验 同一受试者依次接受多种处理,自身作为对照
洗脱期 两次给药之间的间隔,用于清除前一次药物
双盲 受试者与实施者均不知当前处理
hERG 快速延迟整流钾通道,其阻滞与 QT 延长强相关
晚钠电流 钠通道失活延迟形成的持续内向电流
J 点 QRS 终点,心室除极结束、复极开始的位置
J-Tpeak J 点到 T 波峰的间期,代表早期复极
Tpeak-Tend T 波峰到终点的间期,代表晚期复极
QTc 按心率校正后的 QT 间期
Fridericia 校正 QTc = QT / RR 的三次方根,心率快时比 Bazett 稳
中位搏 多个心搏对齐后逐点取中位得到的合成波形
向量合成导联 三个正交分量平方和开方得到的幅值导联
界标 波形上的解剖学时间点,如 P 起点、T 终点
名义时点 方案规定的时间点,实际采血可能略有偏移
暴露-反应 以血药浓度为横轴、效应为纵轴的剂量替代分析
尖端扭转型室速 一种多形性室性心动过速,与复极延长相关
替代终点 用来代替临床结局的中间指标
跨壁复极离散 心外膜与心内膜复极完成时间的差异
WFDB PhysioNet 的波形数据库格式
.hea 纯文本头文件,声明采样率、增益与导联
.atr 二进制注释文件,存放界标位置与符号
EGREFID 心电唯一标识,UUID 字符串
RANDID 受试者随机号
ODC-BY 开放数据共享署名许可

附录 A:核心数字核对表

项 值 来源 来源层级
受试者数 22 官方页面摘要 官方页面
给药期数 5 官方页面摘要 官方页面
洗脱期 7 天 官方实验方法段 官方页面
时点数 16 官方实验方法段 官方页面
每点时相数 3 官方实验方法段 官方页面
原始片段数 5,232 官方实验方法段 官方页面
中位搏数 5,223 官方文件段 官方页面
采集采样率 500 Hz 官方实验方法段 官方页面
发布采样率 1000 Hz 头文件首行 官方文件
幅度分辨率 2.5 μV 官方实验方法段 官方页面
导联数 12(中位层 16) 官方页面与头文件 官方文件
每段采样点 10000(中位层 1159) 头文件首行 官方文件
解压体积 1.4 GB 官方文件列表 官方页面
临床表列数 33 列 列说明文件 官方文件
记录清单行数 10,455 RECORDS 官方文件
许可 ODC-BY 1.0 官方页面 官方页面
DOI 10.13026/C2HP45 官方页面 官方页面
发布日 2016-07-26 官方页面 官方页面

附录 B:数字的来源分层

第一层,官方页面与官方文件。 受试者数、给药期、洗脱期、时点、采样率、片段数、中位搏数、体积、许可、DOI、列名,全部来自项目主页与随库发布的文本文件。这一层的数字可以直接引用。

第二层,论文摘要。 四种药的通道作用分类、J-Tpeak 与 Tpeak-Tend 的机制解释、两篇论文的期刊与年份,来自 Europe PMC 返回的摘要与作者单位。摘要只能支撑「论文这样主张」,不能支撑「机制已被完全确认」。

第三层,未核实。 缺失九条中位搏的具体原因、标注的一致性统计、研究中心的确切数量、连续记录是否可申请。正文中涉及这些的地方都做了限定表述,没有给出具体数值。

附录 C:完整参考文献

编号 文献 链接 用途
1 ECGRDVQ 项目主页 v1.0.0 https://physionet.org/content/ecgrdvq/1.0.0/ 全部规模与结构数据
2 项目文件目录 https://physionet.org/files/ecgrdvq/1.0.0/ 头文件、清单、临床表
3 Johannesen L 等,Clin Pharmacol Ther 2014 https://doi.org/10.1038/clpt.2014.155 试验设计与主要结论
4 Vicente J 等,J Am Heart Assoc 2015 https://doi.org/10.1161/JAHA.114.001615 T 波形态测量方法
5 PhysioNet 平台综述,Nature Health 2026 https://doi.org/10.1038/s44360-026-00096-z 托管与引用规范
6 ClinicalTrials.gov NCT01873950 https://clinicaltrials.gov/study/NCT01873950 试验注册信息
7 WFDB 格式说明 https://physionet.org/physiotools/wfdb.shtml 头文件与注释格式
8 BUT QDB(对照) https://physionet.org/content/butqdb/1.0.0/ §6.2 的区隔
9 CiPA 心电验证研究(对照) https://physionet.org/content/[ecgcipa](https://www.qianfanghub.com/ai-ready-dataset/ecgcipa/1261)/1.0.0/ §6.3 的区隔

附录 D:任务代码

任务:把一条中位搏的界标读成一张间期表

import wfdb
import pandas as pd

def beat_intervals(name, pn_dir="ecgrdvq"):
    #-- 读中位搏波形与注释
    rec = wfdb.rdrecord(name, pn_dir=pn_dir)
    ann = wfdb.rdann(name, "atr", pn_dir=pn_dir)
    fs = rec.fs

    #-- 按本库实际使用的三类符号分组
    order = list(zip(ann.sample, ann.symbol))
    starts = [s for s, sym in order if sym == "("]
    ends   = [s for s, sym in order if sym == ")"]
    tpeaks = [s for s, sym in order if sym == "t"]

    if len(starts) < 2 or len(ends) < 2 or not tpeaks:
        return None

    ms = lambda a, b: (b - a) / fs * 1000
    return {
        "record": name.split("/")[-1],
        "PR": ms(starts[0], starts[1]),
        "QRS": ms(starts[1], ends[0]),
        "QT": ms(starts[1], ends[-1]),
        "JTpeak": ms(ends[0], tpeaks[0]),
        "TpeakTend": ms(tpeaks[0], ends[-1]),
        "n_marks": len(order),
    }

rows = []
for m in ["00ed2097-cd14-4f03-ab33-853da5be5550"]:
    r = beat_intervals(f"medians/1001/{m}")
    if r:
        rows.append(r)
print(pd.DataFrame(rows))

上面列表里的 UUID 取自 §4.3 的案例,可以换成 RECORDS 里任意一条 medians/ 开头的记录。批量跑的时候,先过滤出中位层的行,去掉 medians/ 前缀再传给 wfdb.rdann,注意 pn_dir 模式下路径要保留这一层。

任务:把间期表与临床表对齐,检查口径差

import pandas as pd

cli = pd.read_csv("ecgrdvq_meta/clinical.csv")
cli.columns = [c.strip().lstrip("\ufeff") for c in cli.columns]
cli = cli.loc[:, ~cli.columns.duplicated()]
cli = cli.set_index("EGREFID")

mine = pd.DataFrame(rows).set_index("record")
joined = mine.join(
    cli[["QT", "JTPEAK", "TPEAKTEND", "EXTRT", "TPT"]],
    how="inner", lsuffix="_calc", rsuffix="_table",
)
joined["dQT"] = joined["QT_calc"] - joined["QT_table"]
print(joined.groupby("EXTRT")["dQT"].describe())

这一步的意义不在数值本身,而在于确认「自己算的」与「表里给的」是否同一套口径。差异如果系统性偏大或偏小,说明界标归属判断有误,回到 §5.4 重新核对符号。

附录 E:如果只记五件事

序号 要点
1 它是四个药名的心电效应库,不是质量库,缩写与质量评分无关
2 二十二名健康志愿者、五期交叉、四种机制加安慰剂,自身对照是它的全部价值
3 原始层五千二百余段十秒十二导联,中位层五千二百余条带复极界标
4 界标只在 medians 层,原始段没有逐搏注释;片段是软件择优挑的
5 它证明复极可以分段,不证明任何药安全;替代终点不等于结局

编辑说明

本篇的核验路径与遗留问题集中记在这里,正文不再重复。访问时间均为 2026 年 10 月 28 日。

事实核对以项目主页与其随库文本为准。页面正文、RECORDS、ANNOTATORS、列说明文件、两个 .hea 头文件(原始层与中位层各一份)以及一份 .atr 注释,均经直接访问取得原文;临床表因体积较大未整表下载,仅核对了列说明文件与列名清单。论文信息取自 Europe PMC 的摘要与作者单位字段,未获取全文,因此正文中凡涉及论文结论的表述都停在摘要能支撑的层面。

刻意未做的三件事。其一,没有统计临床表的行级分布,包括年龄区间、性别比例、各处理组的片段数——这些数字官方页面没有给出,自行统计会与「只收规模、结构、边界三类数字」的定位冲突。其二,没有对全库波形做质量评估,因为片段本身已被择优,再评一次只会得到「很干净」这个已知结论。其三,没有推断缺失九条中位搏的原因,官方未说明,任何归因都是猜测。

有一处官方内部不一致需要留意。列说明文件在解释 EGREFID 时写道,心电「存放在 zip 包内,路径为 randid/egrefid.ecg」,而实际目录是 raw/<RANDID>/<EGREFID>.dat 加 .hea,扩展名与层次都不同。这一段描述应当是早期打包方案的遗留,以实际目录为准。

另有一处需要提醒后续维护者:库内已有一条药物心电词条(CiPA),两者主题相邻但来源与规模不同,改稿时不要合并,§6.3 的对比表就是为了防止这种混淆而写的。若将来出现第二版数据,需重核 RECORDS 行数与中位层的缺口,这两处最容易随版本变化。


相关数据集导航

以下为站内 AI-Ready 数据集百科中与本词条共享多个主题标签的相关数据集,按相关度降序排列:

  • ecgdmmld — 共享标签:生理信号 / 心电信号 / 药物安全 / 心血管疾病
  • ecgcipa — 共享标签:生理信号 / 心电信号 / 药物安全 / 心血管疾病
  • multimodal-surgery-anesthesia — 共享标签:生理信号 / 药物安全 / 心血管疾病
  • wctecgdb — 共享标签:生理信号 / 心电信号 / 心血管疾病
  • ahadb — 共享标签:生理信号 / 心电信号 / 心血管疾病
  • chfdb — 共享标签:生理信号 / 心电信号 / 心血管疾病
  • crisdb — 共享标签:生理信号 / 心电信号 / 心血管疾病
  • cudb — 共享标签:生理信号 / 心电信号 / 心血管疾病
  • ltdb — 共享标签:生理信号 / 心电信号 / 心血管疾病
  • ltstdb — 共享标签:生理信号 / 心电信号 / 心血管疾病

导航说明:本章节由全站统一标签体系自动计算生成(标签重合度算法),双向可达;点击链接可跳转至对应数据集词条。

返回 AI-Ready 数据集