颅脑创伤床旁的三根管线 — CHARIS 颅内压监护波形库

13 名患者 / 50 Hz 三通道 / 1.6 GB 开放下载

来源 https://physionet.org/content/charisdb/1.0.0/发布时间: 2026-10-28最后更新: 2026-10-28 阅读 15
颅脑创伤床旁的三根管线 — CHARIS 颅内压监护波形库

信息速览

数据集名称颅脑创伤床旁的三根管线 — CHARIS 颅内压监护波形库
数据类型时序信号,波形,元数据,原始数据链接
规模13 名患者 / 13 条记录
接入方式https://physionet.org/content/charisdb/1.0.0/
AI 就绪度

颅脑创伤患者进入重症监护室之后,医生要看的东西比普通病房多一样:颅腔里的压力。颅骨是一个闭合的壳,里面装着脑组织、血液和脑脊液,任何一部分体积增加都会把压力顶上去,而压力一旦超过阈值,灌注就下降,缺血又会反过来加重水肿。临床上处理这件事的办法很直接——在额部钻一个小孔,把一根传感器送进脑实质,或者在脑室里放一根引流管,把压力读出来,接在床旁的监护仪上,让它和心电图、动脉血压一起滚成三条曲线。

这三条曲线放在同一个时间轴上,就有了一个别处得不到的对照关系:心率代表全身的循环节律,动脉血压代表流入颅腔的灌注压力,颅内压代表颅腔内部的对抗压力。三者之间的互动,是脑血管自动调节功能最直观的读数。CHARIS 数据库收录的正是这种三通道同步记录,来自美国新泽西州一家医学中心的外科重症监护室,由罗格斯大学的研究组在 2017 年交给 PhysioNet 公开。

它的体量很小,公开部分只有十三名患者,这与它在方法学上的意义并不相称——不少关于压力反应指数的早期讨论,用的就是这批记录。因此它更像一份可以逐条读完的原始档案,而不是一个可以反复喂给模型的语料池。一屏速览见下表。

维度 内容
全名 CHARIS database
发布方 PhysioNet(原始数据由罗格斯大学 CHARIS 项目贡献,William Craelius 主持)
首次发布 2017 年 1 月 19 日,版本 1.0.0
最近改动 2019 年 2 月 20 日,目录内校验和清单更新
DOI 10.13026/C24G6F
记录数 13 条(charis1 至 charis13)
患者数 13 名(公开部分);论文摘要所述研究队列为 29 名
通道数 3(ECG、ABP、ICP),逐条记录一致
采样率 50 Hz
模拟前端 通用电气 TRAM-rac 4A,隔离并经 25 Hz 截止滤波
压力分辨率 0.14 mmHg(官方页面标注,对应 ±500 mmHg 动态范围)
未压缩体积 1.6 GB
文件格式 WFDB:.hea 头文件 / .dat 信号
临床字段 年龄、性别、诊断缩写、转归
许可 ODC-BY 1.0,免注册
典型用途 颅内高压事件回顾、压力反应指数复核、多通道时序流水线验证

§1 它要解决的具体麻烦

1.1 一条压力曲线不够,要三条对齐才算数

把颅内压单独画出来,看到的是它的绝对水平;把动脉血压单独画出来,看到的也是绝对水平。但临床真正关心的问题不在绝对水平上,而在两者如何联动上。正常人的脑血管有自动调节能力:灌注压升高时,脑小动脉收缩,阻力上升,血流维持稳定;灌注压下降时则相反。这种调节一旦失效,血流就跟着压力被动波动,脑组织对缺血和充血都失去缓冲。

要在床旁判断调节能力,只有两条路。第一条是主动测试,比如短暂压迫颈动脉或者改变体位,观察血流反应,这在重症患者身上风险高,做不了几次。第二条是被动观察,把动脉血压和颅内压放在同一时间轴上,看颅内压是否随着血压起伏——如果同向同步起伏,说明调节已经失效,这就是压力反应指数(PRx)背后的思路。它不需要额外操作,只需要两条已经存在的信号,以及它们严格同步的时间戳。

这正是 CHARIS 存在的理由。它不是一份通用监护波形库,而是围绕一种特定的计算方法搭建起来的。论文摘要里说得很清楚:研究组的系统从病房现有的监护仪上截取信号、压缩、再标准化地搜索各种候选指数与不良事件的关系,并配了一个自动事件探测器来定位颅内压升高的片段、剔除伪迹。

1.2 三条常见的错误期待

第一条,期待它是「颅脑创伤的有效样本」可以拿去做训练。这个期待在规模上就会落空。公开的十三条记录,在患者层面就是一个两位数的样本,任何深度网络都能在一两个轮次内把它记熟。它适合回答「这个方法在这几种情况下会不会算错」,不适合回答「这个方法有多大效能」。

第二条,期待它有逐事件的标签文件。整个目录里只有 .hea 和 .dat,没有 .atr 之类的注释文件,也没有事件表。颅内高压事件要自己从颅内压通道上按阈值切出来。论文里提到的那套自动事件探测器,是研究组的软件组件,不在这份数据里。

第三条,期待它的诊断字段能当一个干净的队列标签。头文件里的诊断行是一串缩写,有的记录写 (TBI),有的写 (SDH/TBI),有的写 (CVA),还有两条记录根本没有这一行。它记录的是当时病历上的简要结论,而不是一套互相排斥的分组定义。

1.3 它能给到的与给不到的

你的需求 它给的 够不够
三通道长时间同步记录 每条记录单一时间轴上的 ECG、ABP、ICP 够,且无需自己做对齐
颅内高压事件的回顾性分析 连续的颅内压通道,可自行按阈值切事件 够做方法演示,样本太少不能做统计推断
PRx 等自动调节指数的复核 血压与颅内压同时可用的原始波形 够,这是它的设计用途
用于训练的事件预测模型 十几条记录 不够,患者级样本量过小
丰富的临床上下文(用药、评分、影像) 年龄、性别、诊断缩写、转归 不够,只有四类字段
波形形态精细分析 50 Hz 采样,25 Hz 滤波上限 受限,颅内压脉搏波的细节被削平
多中心泛化验证 单一中心、单一病房 不够
完整的官方标注 无注释文件、无事件表 不够,标签全部需要自建

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

你的处境 它能帮你什么 下一步该做什么
你在做压力反应指数的算法,想找一份能跑通的原始数据 提供血压与颅内压同源的连续波形,正好是计算 PRx 所需的两路输入 先按官方说明确认窗口长度,再在颅内压间断的段落上做标记,避开这些时段
你在搭建重症波形处理流水线,需要小而全的样本 十三条记录、三通道、WFDB 格式,一小时内能下完并解析完 用这一批把读写、滤波、切窗、绘图四步都跑一遍,再换大库
你要评估某个公开的颅内高压预测结果 提供复核所需的原始信号,可以重算阈值事件与作者对齐 先确认原作者用的阈值与窗口,再复算一遍,比对事件数
你在做脑自动调节的教学 三条曲线的联动关系可以画成一张清楚的图 选一条颅内压升高的段落,把三条曲线上下排列,标注对应时刻
你想做多通道生理信号的跨库迁移 它与其它 ICU 波形库通道集不同,正好当外部集 只保留三路共有通道,其余按缺失处理,并在文中说明
你要做一个面向神经重症的大规模模型 提供的是方法学参照,不是数据材料 去用规模更大的 ICU 波形库,把它留作小样本验证

1.5 一句话判断

它不是一份用来喂模型的数据,而是一份用来检验算法的原始档案:十三条真实的颅腔压力曲线,记录着一个方法在被做成产品之前的样子。

1.6 不适合谁:四条边界

不适合拿它做训练的规模来源。 十三条记录,患者级样本量是个位数加个位数,任何参数化模型的成绩都会先反映随机初始化而不是数据规律。

不适合拿它做无标注医学影像或诊断推理。 它没有影像,没有报告,没有诊断标签的体系。它只有三条压力与电压曲线,外加一行病历摘要。

不适合拿它代表「颅脑创伤人群」。 公开的十三条里有脑血管病和蛛网膜下腔出血的病例,官方描述的人群是「诊断为脑损伤并需要置入颅内压探头或脑室引流管」的患者,范围比单纯创伤更宽。

不适合做跨中心、跨设备的评价。 全部记录来自同一家医院同一个病房,用的是同一款监护仪的模拟输出。设备带宽、滤波设置、护理操作习惯全部固定,跨域差异无从估计。

§2 数据构成与规格

2.1 一条记录只有两个文件

数据库沿用 PhysioNet 的标准波形格式 WFDB。每一名患者对应同名的两个文件:.hea 是纯文本头文件,.dat 是二进制信号本体。没有注释文件,没有附加的临床数据表,没有事件清单。这一点与很多心电图库不同——那些库至少有 .atr 存放心搏标注,而这份库里这一类文件完全缺席。

.dat 内部按采样点交错排列三个通道:第 1 个采样点的 ECG、ABP、ICP,接着第 2 个采样点,依此类推。每个采样值是 16 位有符号整数,换回物理量要靠头文件里每通道的增益与基线。头文件很小,最长的一条也只有两百六十字节左右,却把整段记录可计算所需的全部参数都装了进去。

体积上,十三条记录的 .dat 合计约 1.6 GB,单条从四十余兆到三百八十余兆不等,差距主要来自记录长度而非采样率——采样率全部是 50 Hz,通道全部是三路。

2.2 字段与记录的完整字典

先说 .hea 首行。它由五段组成:记录名、通道数、采样率、采样点数。以 charis1 为例,读出来是 charis1 3 50 12239851,意思是这条记录叫 charis1,有 3 路信号,每秒采样 50 点,整段共 12239851 个采样点。按 50 Hz 折算,这是一段约六十八小时的记录。

其后是三条通道定义行,每行的字段依次是文件名、存储格式、增益与基线、单位、若干保留位(全为零)、初始值、通道名。最后一行以井号开头,是自由文本的患者信息,格式并不统一。

字段 所在位置 取值形态 说明
记录名 .hea 首行第 1 段 charis1 … charis13 同时是 .dat 的文件名主干
通道数 .hea 首行第 2 段 恒为 3 13 条记录完全一致
采样率 .hea 首行第 3 段 恒为 50 单位 Hz
采样点数 .hea 首行第 4 段 七位数至九位数 除以 50 得秒数
存储格式 通道行第 2 段 恒为 16 16 位整数,单文件交错
增益与基线 通道行第 3 段 形如 85.953(-1332) 括号内为基线,斜杠前为增益
物理单位 通道行第 4 段 mmHg 或 mV 压力通道用毫米汞柱,心电用毫伏
初始值 通道行第 7 段 有符号整数 供校验与重采样参考
通道名 通道行第 8 段 ABP、ECG、ICP 顺序在多数记录中为 ABP、ECG、ICP
患者信息行 文件末行 形如 <age>: 19 <sex>: M <diagnoses>: (SAH/SDH/TBI) <outcome>: Rehab 并非每条记录都有
备注行 文件末行 形如 Intermittent,discontinuous ICP signal 仅个别记录出现

三类信息值得单独说明。

第一类是增益。它把整数采样值换算回物理量,公式是物理值等于采样值除以增益再加上基线修正。不同记录的增益差别不小,压力通道的增益大致在六十到一百三十之间,心电通道则统一在六千上下。这意味着同一段波形在不同文件里的整数取值范围可以差一倍以上,任何跨记录合并的处理都必须先按各自头文件做换算,不能直接拼数组。

第二类是单位。ABP 与 ICP 都标 mmHg,ECG 标 mV。心电通道的增益换算之后得到的是毫伏级电压,这个通道与压力通道的物理量纲不同,做归一化时要分开处理。

第三类是患者信息行。这一行的内容完全由贡献者手写,格式没有统一的模板。字段之间用尖括号包裹的标签分隔,但缺少某个字段时整段就消失,没有占位符。因此解析时不能按固定位置取,只能按标签做键值匹配,取不到的记为缺失。

2.3 一条记录的完整解剖

下面以 charis1 为例,把一条记录从头读到尾。这段代码只依赖标准库与几个常用科学计算包,可以直接运行。

#-- 读取一条 CHARIS 记录并还原物理量
import re
import numpy as np

BASE = "https://physionet.org/files/charisdb/1.0.0/"

def read_header(name, local_dir="./"):
    #-- 头文件很小,直接按行读
    lines = open(f"{local_dir}{name}.hea", encoding="utf-8").read().splitlines()
    #-- 首行拆成四段:记录名 通道数 采样率 采样点数
    head = lines[0].split()
    rec, n_sig, fs, n_samp = head[0], int(head[1]), float(head[2]), int(head[3])
    signals = []
    for ln in lines[1:1 + n_sig]:
        parts = ln.split()
        #-- 增益与基线形如 85.953(-1332),用正则拆开
        m = re.match(r"([-\d.]+)\(([-\d]+)\)", parts[2])
        gain, baseline = float(m.group(1)), float(m.group(2))
        unit = parts[3].split("/")[0]
        signals.append({"unit": unit, "gain": gain, "baseline": baseline,
                        "name": parts[-1]})
    #-- 剩余行里以井号开头的是自由文本患者信息
    notes = [ln.lstrip("# ").strip() for ln in lines[1 + n_sig:] if ln.strip()]
    return {"rec": rec, "fs": fs, "n_samp": n_samp,
            "signals": signals, "notes": notes}

def read_signal(name, n_sig, n_samp, local_dir="./"):
    #-- 16 位小端整数,逐采样点按通道交错
    raw = np.fromfile(f"{local_dir}{name}.dat", dtype="<i2")
    #-- 文件可能只下了一部分,按实际长度截断而不是硬取头部
    n_have = len(raw) // n_sig
    raw = raw[: n_have * n_sig].reshape(n_have, n_sig)
    return raw

hdr = read_header("charis1")
arr = read_signal("charis1", 3, hdr["n_samp"])
for i, s in enumerate(hdr["signals"]):
    #-- 整数值除以增益并减去基线,得到毫米汞柱或毫伏
    phys = (arr[:, i] - s["baseline"]) / s["gain"]
    print(s["name"], s["unit"], round(float(phys.min()), 2), round(float(phys.max()), 2))
print("时长小时", round(hdr["n_samp"] / hdr["fs"] / 3600, 1))

跑通之后会看到三行统计,分别是 ABP、ECG、ICP 三路的取值范围,以及整段记录的小时数。函数里那一步按实际文件长度截断的写法值得留意:.dat 是整条写入的,文件没下完时按头文件声明的采样点数去塑形会直接报错,按实际读到的元素数算一次更稳。这一段代码同时也说明了这个库最容易被误读的地方:解剖一条记录不需要读完全部 1.6 GB,单条头文件加单条 .dat 就足够。

再往下看一条记录的结构层次:

层次 内容 是否逐条完整 备注
设备层 监护仪型号、滤波设置 全库统一 官方说明为一款四槽监护仪
采样层 50 Hz、16 位、三路交错 全部一致 无缺通道记录
通道层 ABP、ECG、ICP 命名 全部一致 顺序也基本一致
记录层 单条连续,未切片 全部一致 一条记录即一次住院全程
患者层 年龄、性别、诊断、转归 部分缺失 有两条记录无患者信息行
事件层 颅内高压事件 全部缺失 需按阈值自建

2.4 规模、时长与通道的分布

把十三条记录的头文件放在一起看,能读出三个维度的分布:长度、通道组成、元数据完整度。

长度方面,采样点数从七位数到九位数跨度不小。短的一条约七百万点,折算四十小时;长的一条近六千八百万点,折算约三百七十五小时。其余记录分布在这两端之间,多数落在数十小时到一百多小时。这个跨度本身说明采集不是按固定时长切的,而是按住院时长走,患者住了多久就录了多久。

记录 采样点数(约) 折算时长(约) 体积档位
charis1 一千二百二十四万 六十八小时 七十兆
charis2 六千七百五十万 三百七十五小时 三百八十兆
charis3 一千七百一十万 九十五小时 约一百兆
charis4 七百二十万 四十小时 四十兆
charis5 三千六百万 二百小时 二百兆
charis6 八百二十八万 四十六小时 四十七兆
charis7 二千四百一十八万 一百三十四小时 一百三十八兆
charis8 一千七百一十七万 九十五小时 九十八兆
charis9 三千零七十八万 一百七十一小时 一百七十六兆
charis10 二千一百二十八万 一百一十八小时 一百二十二兆
charis11 一千七百三十三万 九十六小时 九十九兆
charis12 二千零五十五万 一百一十四小时 一百一十八兆
charis13 一千四百二十二万 七十九小时 八十一兆

通道组成方面没有例外:十三条记录全部是三通道。这看起来单调,实际上是一个有价值的性质——不存在某些库那样的「明明叫多通道,一半记录只有两路」的情况。做批量处理时,可以假定通道结构恒定,把注意力放在信号内容上。

性质 取值 覆盖范围
通道数 3 全部 13 条
采样率 50 Hz 全部 13 条
存储格式 16 位整数 全部 13 条
单位组合 mmHg、mV、mmHg 全部 13 条
含患者信息行 有 多数记录
含间断性颅内压备注 有 个别记录
含性别字段 有 多数记录,一条缺
含转归字段 有 多数记录

元数据完整度方面,差距明显。多数记录带完整的四项:年龄、性别、诊断、转归。有一条记录缺性别字段只剩年龄、诊断和转归;有两条记录整行缺失,头文件在通道定义之后就结束。这种不整齐在人工整理的小库中很常见,处理时必须按字段存在性判断,不能假定格式一致。

2.5 与同类资源的字段差异

把 CHARIS 与几类常见的重症与脑相关资源放在一起,字段层面的差异一目了然。

资源类型 通道构成 采样率 临床字段 标注
CHARIS ECG、ABP、ICP 50 Hz 年龄、性别、诊断、转归 无
通用 ICU 波形库(高采样档) 多导联 ECG、ABP、PPG、呼吸等 一百赫兹以上 由关联的临床表提供 部分库有心律标注
儿科神经重症颅内压库 颅内压、动脉压、经颅多普勒 一百赫兹以上 较少 无
脑电库 头皮或颅内脑电多导 二百赫兹以上 较少 逐段发作标注
颅脑创伤影像库 影像序列 不适用 影像报告与评分 病灶分割

两个差别值得强调。其一是采样率。CHARIS 的五十赫兹在重症波形库里属于偏低的一端,这是设计选择而不是缺陷:为了把整段住院录下来,必须压采样率与体积。其二是没有标注。大多数现代波形库至少提供心律或事件注释,而这批记录完全没有,全部事件都得由使用者按阈值重建。

这两点合起来决定了一件事:CHARIS 与「现代重症监护波形库」不是同类替代关系。前者是围绕一个研究问题搭起来的、可以逐条读完的档案;后者是围绕机器学习任务搭起来的、以规模取胜的素材池。

§3 它是谁的档案:一个实验室的采集装置

3.1 数据来自一台自己接的采集器

这套数据的采集方式不是把监护仪的数据导出,而是从监护仪的模拟输出端接线上取信号。官方说明写得很具体:采集单元连接在重症监护室床旁监护仪上,通过一款通用电气四槽监护仪的隔离与滤波输出取得信号,再送进采集设备。滤波截止频率是二十五赫兹。

理解这一点,对使用很重要。它意味着信号的带宽上限在设计阶段就被定死了:二十五赫兹以上的成分在进入计算机之前就已经被削掉,之后的任何数字滤波都找不回来。心电的 QRS 波最陡的斜率、动脉压波形的重搏切迹、颅内压脉搏波的三峰结构,都在这个上限附近,各自损失不同比例。

采集的启动条件也值得注意。采集单元在「诊断为脑损伤且需要置入颅内压探头或脑室引流管的患者到达时」被激活。这是一个很具体的入组条件,它把人群限定在需要做有创颅内压监测的那一部分——不是所有颅脑损伤患者,而是其中的重症部分。

3.2 传感器与压力测点

三条通道的来源各自不同,理解这一点才能判断每条通道的可靠性。

心电通道来自监护仪的体表心电通道,在重症监护室内通常是三导联或五导联贴片,主要用于心律监测,不用于诊断级形态分析。它在数据里的角色更多是节律参考:判断某一时段是否有心动过速或心律失常,为压力信号的解读提供背景。

动脉血压通道来自桡动脉置管。官方说明使用的是充满液体的导管,由压力传感器把压力转成电信号。这种测压方式在重症监护里很常见,优点是连续,缺点是对管路位置与零点校准敏感,翻身、抬高床头、管路打折都会在波形上留下台阶。

颅内压通道有两种来源。多数情况下用的是脑实质内的微传感器,直接插在额部的脑组织中;少数情况下颅内压只能从脑室引流管间断取得。前一种是连续压力信号,后一种只在操作时才有读数。两种来源的物理性质不同,混在一起会让颅内压通道在整段记录中出现长段的平坦或者脱落。

3.3 为什么这三条、不是别的三条

选择 ECG、ABP、ICP 而不是别的组合,是任务决定的。计算压力反应指数只需要颅内压与动脉血压,心电是附加的节律参考。这三条通道构成了「颅腔内压力如何响应全身循环」的最小完整集合。

三个更常见的候选通道被排除在外,每一个都有理由:血氧饱和度的响应时间与压力不同步,放进同一时间轴会引入额外的滞后;呼吸通道与压力关系复杂,且在多数病房里靠阻抗法取得,噪声大;脑电或脑血流需要额外设备,不在常规床旁监护范围内。

这也解释了为什么这一批数据的通道数恒定为三——它不是从更大的通道集合里挑出来的,而是从一开始就只接了三路。

3.4 记录的形成过程

一条记录从采集到进入公开库,经过的环节大致如下:

环节 动作 留下的痕迹
入组 患者到达并置入颅内压装置时激活采集 记录起点即入组时刻
采集 三路模拟信号经隔离与滤波后数字化 25 Hz 上限、50 Hz 采样
存储 按患者顺序写入单一数据文件 一行记录即一次住院
描述 手工补写年龄、性别、诊断、转归 格式不统一、部分缺失
注释 个别记录补写采集异常说明 间断颅内压、患者断开
归档 转成 WFDB 并加头文件 2017 年首次发布

这个链条里唯一没有的环节,是事件标注。采集时不一定产生,归档时也没有补做。所有使用这个库的人,都要自己在颅内压通道上按阈值找事件。

§4 它最独特的东西:把颅腔的压力摊在同一张纸上

4.1 三条曲线的共同时间轴

大部分公开的颅脑创伤数据给的是离散的、按小时聚合的数值,比如每小时的颅内压均值、最大最小值。这类数据能做队列分析,但做不了逐分钟的机制观察。CHARIS 给的是原始的、未聚合的波形,而且三条通道共享同一个采样时钟。

共享时钟这件事比听起来重要。计算压力反应指数要求取一个短窗口(临床上常用五分钟量级的移动窗口),在这个窗口里对颅内压与动脉血压做线性回归,取斜率。两路信号之间哪怕有几百毫秒的时滞,斜率都会变形。用这个库可以免去对齐工作:.dat 文件内部本来就是按采样点交错的,同一个索引号对应的就是同一时刻的三路值。

4.2 案例:charis9 的间断性颅内压

在十三条记录里,charis9 值得单独拿出来看,因为它的头文件里写了两行备注,把这份数据的两类典型缺陷都点到了。

第一行写的是「Intermittent,discontinuous ICP signal」,意思是这条记录的颅内压信号是间断的、不连续的。这与官方说明里提到的情形吻合:部分患者的颅内压只能从脑室引流管取得,只有在护士或医生操作引流时才有读数,其余时间通道上要么是平坦的基线,要么是脱落之后的漂移。

第二行写的是「Patient disconnected at end of recording」,意思是患者在记录末尾断开连接。这通常对应着转出监护室、拔管、或者检查时临时断线。

这两条备注合在一起,说明了一个在使用时极易被忽略的事实:颅内压通道存在的不等于颅内压数值有效。如果直接按固定窗口做统计,间断段会以两种方式污染结果:平坦段会把标准差压到接近零,漂移段会把均值拉向极端值。两种都会让以变异程度为输入的指数失真。

处理的办法很朴素,但要写进流程:

#-- 在切窗之前,先把颅内压的无效段标出来
import numpy as np

def mark_icp_valid(icp, fs=50):
    #-- 一阶差分,捕捉突变与平台
    d = np.abs(np.diff(icp, prepend=icp[0]))
    #-- 长时间完全不动 = 脱落或平坦,用滚动标准差判断
    win = int(fs * 30)  #-- 30 秒窗口
    from numpy.lib.stride_tricks import sliding_window_view
    if len(icp) < win:
        return np.zeros(len(icp), dtype=bool)
    sd = np.array([v.std() for v in sliding_window_view(icp, win)])
    flat = np.repeat(sd < 0.05, win)[: len(icp)]
    #-- 单点跳变过大 = 操作或干扰
    jump = d > 20.0
    return ~(flat | jump)

这段代码只是把两类明显无效的段标出来,不涉及更高阶的伪迹判别。对 charis9 这条记录,先跑一遍这一步,就能看出可用时段究竟剩下多少,再决定后续窗口怎么切。

同样的处理在 §4.1 的三通道对齐讨论里也适用——对齐是必要条件,有效样本才是充分条件。这个区别在规模大的库里容易被平均掉,在小库上却直接决定结论。

4.3 颅内高压的处理背景

官方说明里有一句关于临床处置的话:颅内压超过二十毫米汞柱时,用甘露醇推注和轻度过度通气处理。这一句很短,却是理解整段记录的钥匙。

它说明在记录期间,颅内压的升高不是一个被动的观察对象,而是被反复干预的。患者压升高了就打甘露醇、调呼吸机,压力回落后继续观察。这意味着颅内压曲线上那些「升上去又下来」的形态,有相当一部分是治疗造成的,而不是自然病程。任何把颅内压升高的幅度当作严重程度指标的分析,都必须把这一层考虑进去。

对做预测模型的人来说,这还引出一个更麻烦的问题:如果模型学会了识别「甘露醇之后的回落」,它在真实前瞻场景里的表现会与回顾性评估差得很远,因为前瞻时它看不到决策之后的信号。这是几乎所有重症回顾数据共有的问题,在这份数据上尤其突出,因为记录里唯一可见的干预痕迹就是压力曲线本身。

4.4 体量与时间分辨率的权衡

把这份数据与「更高采样率但更短时长」的记录对比,能看清它的定位。

取舍 高采样短时长 CHARIS 的做法
采样率 一百赫兹以上,保留波形细节 五十赫兹,够做趋势与斜率
单条时长 十几分钟到几小时 数十小时到三百余小时
通道数 三到八路不等 三路固定
事件标注 常有 无
适用任务 形态学、心搏检测 趋势、指数、事件回顾

这个取舍背后有一个判断:对压力反应指数这类指标来说,窗口是分钟级的,五十赫兹的采样率完全够用。用高频采样去算一个五分钟窗口的回归斜率,多出来的信息换不来精度。反过来说,如果任务是识别颅内压脉搏波的三峰形态,五十赫兹就不够了,这时候该换别的库。

§5 怎么拿到、怎么算

5.1 下载路径与体积规划

官方入口在 PhysioNet 的项目页,数据文件放在版本目录下。整个目录不打散用文件管理器点下来更好,因为 .dat 单条就有几百兆。

#-- 整目录同步,支持断点续传
wget -r -N -c -np https://physionet.org/files/charisdb/1.0.0/

#-- 或者用 AWS 命令行,走公开桶,不需要账号
aws s3 sync --no-sign-request s3://physionet-open/charisdb/1.0.0/ ./charisdb/

#-- 只要头文件先看结构,可以单独拉
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13; do
  wget -q "https://physionet.org/files/charisdb/1.0.0/charis${i}.hea"
done

体积规划上,未压缩合计约 1.6 GB,最大单条不到四百兆。这个体量对任何一台笔记本都是可承受的,不需要分片下载,也不需要外接存储。相对地,它无法像大库那样「只取某一段」——WFDB 的单一 .dat 文件不支持按记录内偏移访问,只能整条读。

5.2 用官方工具链读

最快的方式是用 WFDB 的 Python 包,它把头文件解析与信号还原都封装好了。

#-- 需要先 pip install wfdb numpy
import wfdb
import numpy as np

#-- 本地目录下 charis1.hea 与 charis1.dat 并列即可
rec = wfdb.rdrecord("charisdb/charis1", physical=True)
print(rec.sig_name)      #-- 三路通道名
print(rec.fs)            #-- 采样率
print(rec.p_signal.shape)  #-- 采样点数乘通道数
print(rec.comments)      #-- 患者信息行与备注行

#-- 取前十分钟,画颅内压
idx = rec.sig_name.index("ICP")
seg = rec.p_signal[: 600 * 50, idx]
print("十分钟内颅内压中位数", float(np.nanmedian(seg)))

physical=True 会按头文件里的增益与基线把整数转成物理量,这是必须的;默认的 physical=False 给出的是原始整数,直接当毫米汞柱用会差出一个数量级。

5.3 在颅内压通道上切事件

官方没有事件表,所以事件必须自建。常用做法是滑动窗口找超过阈值的段,再做最小时长与合并距离约束。

#-- 按阈值切颅内高压事件,带最短持续与合并间隔
import numpy as np

def find_ih_events(icp, fs=50, thr=20.0, min_minutes=5, merge_gap_min=10):
    above = icp >= thr
    #-- 找连续为真的区间
    edges = np.diff(above.astype(int), prepend=0, append=0)
    starts = np.where(edges == 1)[0]
    ends = np.where(edges == -1)[0]
    events = []
    for s, e in zip(starts, ends):
        #-- 太短的不算一次事件,多半是伪迹
        if (e - s) / fs / 60.0 < min_minutes:
            continue
        if events and (s - events[-1][1]) / fs / 60.0 <= merge_gap_min:
            #-- 间隔太近,与上一段合并
            events[-1] = (events[-1][0], e)
        else:
            events.append((s, e))
    return events

icp = rec.p_signal[:, rec.sig_name.index("ICP")]
ev = find_ih_events(icp)
print("时长超过五分钟的颅内高压段数", len(ev))
for s, e in ev[:5]:
    print(round(s / 50 / 3600, 2), "至", round(e / 50 / 3600, 2), "小时")

阈值、最短持续、合并间隔三个参数没有唯一正确值。论文里的自动事件探测器用的是它自己的参数,公开库没有把参数写下来。使用者复现时应在文中报告自己用的值,否则不同研究之间的「事件数」不可比。

5.4 计算压力反应指数

压力反应指数的定义是:在一个滑动窗口内,把颅内压作为因变量、动脉血压作为自变量做线性回归,取斜率。斜率接近零或为负,说明颅内压不跟着血压走,调节尚存;斜率为正且绝对值大,说明两者同向联动,调节受损。

#-- 逐窗口计算压力反应指数
import numpy as np

def rolling_prx(abp, icp, fs=50, win_sec=300, step_sec=60):
    w, s = int(win_sec * fs), int(step_sec * fs)
    out_t, out_v = [], []
    for start in range(0, len(icp) - w, s):
        x = abp[start:start + w]
        y = icp[start:start + w]
        #-- 窗口内任一路全为常数就不算,回归无意义
        if np.nanstd(x) < 1e-6 or np.nanstd(y) < 1e-6:
            continue
        slope = np.polyfit(x, y, 1)[0]
        out_t.append((start + w / 2) / fs / 60.0)
        out_v.append(slope)
    return np.array(out_t), np.array(out_v)

t_min, prx = rolling_prx(rec.p_signal[:, 0], rec.p_signal[:, 2])
print("可用窗口数", len(prx))
print("斜率分位数 10/50/90", np.round(np.percentile(prx, [10, 50, 90]), 3))

窗口长度的选择会直接影响结果:窗口太短,噪声主导,斜率的方差极大;窗口太长,会把不同生理状态混在一起。临床上习惯用的区间是分钟量级,但具体值没有统一标准,报告时同样要写明。

5.5 与关联的临床表合并

这个大库本身不带逐时点的生命体征表,只有一行摘要信息。如果研究需要更多临床变量,只能从别处获取,且这种合并通常只在同一机构内部可行。

#-- 只把患者信息行解析出来,拼成一张表
import re

rows = []
for i in range(1, 14):
    h = wfdb.rdheader(f"charisdb/charis{i}")
    txt = " ".join(h.comments)
    age = re.search(r"<age>:\s*(\d+)", txt)
    sex = re.search(r"<sex>:\s*([MF])", txt)
    diag = re.search(r"<diagnoses>:\s*\(([^)]+)\)", txt)
    out = re.search(r"<outcome>:\s*([A-Za-z/]+)", txt)
    rows.append({"rec": f"charis{i}",
                 "age": int(age.group(1)) if age else None,
                 "sex": sex.group(1) if sex else None,
                 "diag": diag.group(1) if diag else None,
                 "outcome": out.group(1) if out else None})

这张表一共十三行,可以直接打印出来贴在脚本开头当索引。注意有些记录的诊断字段是多个缩写的组合,不能直接当成单一类别。

5.6 什么时候该换库

判断标准很简单:当你需要的样本量超过两位数,或者需要采样率高于五十赫兹,或者需要逐时点的临床变量时,这个库就不够了。它在那些场合的作用是当流程验证的样本——先用它把读写、换算、切窗、指数计算、绘图整条链路跑通——§4.2 的案例所示的颅内压间断问题,也要在这一步就写进流水线,再把同一套代码换到大库上跑。这样做的好处是调试成本极低,一次下载、一次解析,几秒钟就能看到结果。

§6 与库内条目的关系

6.1 关系图谱

CHARIS 在生理信号这一类词条里的位置,可以用两个轴摆出来:一条是「是否以颅腔压力为一等公民」,另一条是「采样率与临床字段的丰富度」。

词条 与 CHARIS 的关系 分工
MIMIC-IV-Waveform 同为 ICU 波形库,规模大得多、通道多得多 它做规模,CHARIS 做针对性的单问题复核
Neurocritical-Pediatric 同为神经重症颅内压,来源为儿科医院 互补,成人创伤与儿童神经重症各占一端
VitalDB 同为术中与重症监护的多通道生理波形 它覆盖手术全程并带大量临床变量,CHARIS 只覆盖神经重症床旁
PulseDB 侧重血压估计,波形含动脉压 它围绕无袖带血压,CHARIS 围绕颅腔压力
MC-MED 急诊多模态监护含波形与图像 它覆盖急诊多模态,CHARIS 只做单一专科的三通道
AIMS-TBI 同属颅脑创伤主题,但为影像 一个看病灶、一个看压力,互不替代
SICdb、HiRID 分钟级 ICU 数据,数值为主 它们提供聚合后的时间序列与临床表,CHARIS 提供未聚合的原始波形

这张表里最常见的一对混淆是 CHARIS 与大规模 ICU 波形库。两者都叫「重症监护波形」,但一个是以万计的患者与多路高频通道,另一个是十三名患者的低采样三通道。把它们看作同一类的两个版本会误导选型:前者拿来做模型,后者拿来做机制。

6.2 检索路径

你要找的东西 检索词 会落到哪里
颅内压相关公开数据 ICP、intracranial pressure、PhysioNet 本库与 Neurocritical-Pediatric
压力反应指数原始材料 PRx、autoregulation、TBI 本库及引用它的文献
重症多通道波形 ICU waveform、MIMIC-Waveform、HiRID 大规模波形库词条
颅脑创伤影像 TBI MRI、lesion segmentation 影像类词条,与压力无关
动脉血压波形 ABP waveform、arterial line PulseDB、VitalDB 等处
脑电与颅内压对比 EVD、multimodality monitoring 需自行拼合,无单一匹配词条

6.3 分工判据

任务 主粮仓该用什么 CHARIS 的位置 原因
颅内高压预测模型的训练 大规模 ICU 数值或波形库 外部复核样本 患者级样本量只有两位数
PRx 算法开发 无固定替代品 主力之一 血压与颅内压同源同步
脑自动调节的教学演示 本库即可 主力 体积小、图好看、含义清楚
多通道信号处理的流水线验证 任一库皆可 首选之一 下载快、结构简单
药物或干预效果的对比研究 带用药与分组的队列 不适用 无用药记录
影像与波形的多模态研究 配影像的波形库 不适用 无影像

第一行与第三行是这个库最典型的两种用法:一个是在有主粮仓的前提下当裁判,一个是根本不需要主粮仓的知识传播场景。把第二行的用途做好,需要的不是更多的患者,而是更仔细的伪迹处理——这正是 §4.2 的案例想说明的事。

§7 质量评估与局限性

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

在给这份数据打分之前,先纠正一个很常见的误判:把「小」当成「差」。CHARIS 只有十三名患者,这个数字在任何一个以机器学习为中心的评估框架里都会被判为不合格,但如果按它实际承担的用途——为一个计算方法提供原始材料——来衡量,样本量的意义完全不同。

这个校正会改变评价的读法。规模这一项它必然拿不到高分,但在「原始性与针对性的交集」上,它处在少数几个位置之一。混在一起看,就会得出「不值得用」的结论,而这个结论恰恰错过了它唯一无法被替代的地方。

7.1 五维评分

下面按 DAIMS(Data and Information Management System,一套把数据文档、标注、元数据与可重现性拆成可评维度的框架)的常用做法打分,每项一到五分,分数针对「作为神经重症压力信号研究材料」这个用途:

维度 分数 理由
数据规模 1 公开 13 条记录,患者级样本两位数刚出头
信号原始性 5 未聚合、未切片,三条通道共享时钟
标注完备度 1 无注释文件、无事件表、无变量表
文档与元数据 3 采集方式与设备写得很细,但每条记录的字段不齐
可获取性 5 免注册、ODC-BY、体量适中、格式标准

合计十五分(满分二十五)。这个分数结构清楚地说明它不是全能选手:两项满分,两项触底。真正需要判断的是,触底的两项在这个具体用途上是否致命——对于开发一个指数的算法来说,不需要标注,也不需要大规模;但对于任何需要监督信号的任务,这两项就是硬伤。

7.2 信号质量的三层判断

第一层是带内信息。§4.2 的案例已经点出两次滤波叠加的后果,这里只补量化口径:二十五赫兹截止意味着颅内压脉搏波的三峰结构只剩下最慢的成分。对趋势分析完全够,对形态分析不够。判断很直接:如果你要看单个心动周期内颅内压的上升支上升斜率,这个库不行。

第二层是通道有效性。颅内压通道存在不等于有效。部分记录只有间断测值,头文件里用备注行标出来了,但备注不是结构化字段,机器读不到。使用者必须自己在信号上识别平坦段与漂移段,或者读备注行做人工判断。

第三层是时间轴完整性。患者断开连接的那一段,.dat 里通常仍会写入采样点,只是数值没有意义。这意味着采样点数乘以采样率得到的时长,是名义时长而不是有效时长。两者可以差出不少。

层级 判断依据 对下游的影响
带内信息 二十五赫兹截止 形态类指标不可用,趋势类指标可用
通道有效性 备注行与信号平坦度 间断段会压低变异、拉偏均值(§4.2 的案例给出了识别代码)
时间轴完整性 采样点数与断开备注 名义时长大于有效时长
零点正确性 无校准记录 绝对压力值存在未知偏移
节律信息 心电通道采样受限 只能判断大致心率,不能判形态

第四层值得单独提:零点校准。有创压力测量需要定期归零,归零动作会在波形上留下台阶。这份数据没有记录归零时间,也没有提供任何校准信息。因此颅内压的绝对值可信度,取决于护士操作的规范性,而这个信息不在数据里。做相对变化分析受影响较小,做绝对阈值分析受影响较大。

7.3 已知的、可枚举的偏差

偏差 表现 影响
单中心 一家医学中心的一个病房 设备与操作习惯单一,跨域差异无法估计
入组条件偏严 必须需要颅内压装置 只覆盖重症段,轻症不在其中
诊断粒度混杂 TBI、SDH、SAH、ICH、CVA 并列 人群不是纯创伤队列
字段不全 两条记录无患者信息行,一条无性别 分层分析会出现无法归类的样本
采样率偏低 五十赫兹 形态学分析受限
无标注 无事件表 所有标签需自建,跨研究不可直接比
无用药记录 头文件不含药物 无法做干预效果分析
名义与有效时长不符 断开段仍占用采样点 时间归一化的指标会被稀释
队列与公开数不一致 论文写 29 名,公开 13 条 公开部分不能代表整个研究队列

7.4 外部验证矩阵

这类数据最常被引用的方式,是作为某一类指数的原始材料。从公开可查的线索看,其角色大致如下。

验证角色 做法 讲得通的地方 风险
指标准确性复核 按论文参数重算事件与指数 原始波形在手,可逐处对照 参数未公开,复算结果未必一致
流水线冒烟测试 用它跑通读写与切窗 体量小、结构简单 只验证程序能跑,不验证结论
小样本教学演示 取一段升高曲线做图示 三条曲线语义清楚 单例不能代表总体
跨库外部测试 与其它 ICU 波形库并集评估 通道构成不同,可测迁移 样本太少,一次结果波动极大
与儿科颅内压库对照 成人与儿童各取一组 补充成人侧 两侧样本都太小,比较无统计力

矩阵里最值得警惕的是第四行。用一个只有十三条记录的库做外部测试,得到的掉分幅度很大程度上由这十三条的构成决定;换一批记录,结论可能反过来。合理的做法是把它当定性证据而不是定量结论。

7.5 它为何能持续:稀缺的不是数据量,是那三条同时存在的曲线

这个库自 2017 年发布以来没有更新过版本内容,只在 2019 年换过一次校验和清单,却仍然被引用。原因不在规模,而在于它占的位置:需要颅内压与动脉血压同源同步、且能公开获取的原始波形,至今仍然很少。做这类研究的人需要的不是更多患者,而是几条能逐样本看清楚的曲线。只要这个条件不变,它的引用就不会断。

§8 生态位与历史

8.1 从采集系统到公开库

CHARIS 这个名字本身就是项目的缩写:一组人围绕「系统性分析相关生理信号」搭建系统,目标是造出数据驱动的算法,去搜索急性脑损伤患者可能发生的急性临床事件的预测因子。这个定位决定了数据的形态:不是为了做通用监护归档,而是为了支撑一类特定的分析。

采集发生在外科重症监护室的床旁。研究组把采集单元接在现有监护仪的模拟输出上,在患者到达并置入颅内压装置时启动。设备在病房里长期在位,患者来一个录一个。论文报告的采集窗口是十八个月,累计二十九名患者。

公开的部分只有十三条。这个差额是本库最重要的一个未解之处:为什么从二十九名里只放出十三名、放出的这十三名是按什么标准挑的,官方页面没有说明。可以确定的只有事实本身——文件数十三,论文队列二十九。

8.2 与 PhysioNet 托管模式的关系

它进入 PhysioNet 的方式很典型:由一家学术机构整理后捐献,平台负责长期托管与格式规范化。PhysioNet 对这类贡献的要求包括统一的 WFDB 格式、可复现的头文件、清晰的使用许可。CHARIS 全部满足,因此以 ODC-BY 1.0 开放,任何人下载不需注册。

这种模式的好处是长期可访问:域名可能变,但 DOI 与文件路径稳定。代价是平台不承担内容的更新与补充,所以十条记录就是十条,不会随时间增长。

8.3 生态位:机制证据而不是规模证据

把它放进当前的生理信号数据集生态里,位置大致可以这样描述:

坐标系 一端 另一端 CHARIS 在哪
规模 十万级患者 十位数量级 极小端
采样率 数百赫兹 数十赫兹 偏低端
临床字段 数百列变量 无 极少端
针对性 通用 单一问题 极强的一端
标注 逐事件 无 无标注端

这个组合很特殊:它在四根轴上都在「少」的一侧,却在针对性这一根轴上在「多」的一侧。很多库是规模大而针对性弱,或者是针对性强但用了别的形式(比如影像而不是波形)。同时做到「针对性极强」和「原始波形可下载」的并不多,这就是它的生态位。

8.4 谁在用它,用来做什么

从应用角度看,使用者集中在三类。第一类是研究脑自动调节与压力反应指数的临床工程组,用它做方法的原始材料与复核。第二类是重症监护信息化的开发人员,用它做小规模适配与格式验证。第三类是教学与科普,用它展示颅内压与动脉血压的联动关系。

三类用法的共同点是:需求的不是样本数量,而是信号本身的可读性。这也解释了为什么这个库在十几条记录的情况下仍然能存活——它服务的不是统计,而是机制理解。

§9 使用指引

9.1 三种角色的路径

研究者的路径。 先把十三条记录全部下完并解析,做出患者信息汇总表;再逐条检查颅内压通道的有效段,把间断段与断开段标出来;然后按自己选的参数切事件、算指数(有效段的判定参照 §4.2 的案例);最后在与文献对比时明确写出参数差异。这个流程的关键在第二步,跳过它会让后面所有数字都带上偏差。

工程师的路径。 不需要关注临床含义,只把这份数据当成一份格式规整的测试集:解析头文件、还原物理量、按通道拆分、切窗、绘图、导出。五步跑通一遍,就能知道自己写的 WFDB 读写代码是否正确。这一批数据的结构简单到可以作为单元测试的输入。

教学者的路径。 找一条颅内压升高的段落,把三条曲线上下排列画出来,配上时间标注。这个图可以直接说明「压力升高时血压与颅内压在同时变化」这件事,比任何文字描述都清楚。选用时应避开间断颅内压的记录,否则图上会出现解释不了的平坦段。

9.2 一条最短的可用流程

从零开始到画出一张能看的图,最短路径如下:

#-- 一、建目录并取单条记录,先验证流程
mkdir -p charisdb && cd charisdb
wget -q https://physionet.org/files/charisdb/1.0.0/charis1.hea
wget -q https://physionet.org/files/charisdb/1.0.0/charis1.dat

#-- 二、核对校验和,确认下载完整
grep charis1.dat SHA256SUMS.txt 2>/dev/null || \
  wget -q https://physionet.org/files/charisdb/1.0.0/SHA256SUMS.txt
sha256sum charis1.dat
#-- 三、读入、换算、取一段画图
import wfdb
import numpy as np
import matplotlib.pyplot as plt

rec = wfdb.rdrecord("charis1", physical=True)
fs = rec.fs
#-- 取第六小时起的一小时,避开记录开头的置管操作段
a, b = int(6 * 3600 * fs), int(7 * 3600 * fs)
t = np.arange(a, min(b, len(rec.p_signal))) / fs / 3600.0
for name in ("ABP", "ICP"):
    i = rec.sig_name.index(name)
    plt.plot(t, rec.p_signal[a:b, i], lw=0.5, label=name)
plt.xlabel("小时")
plt.legend()
plt.savefig("charis1_first_hour.png", dpi=150)
#-- 四、全库批量生成摘要,供后续筛选
import glob, os, wfdb, numpy as np

rows = []
for hea in sorted(glob.glob("charis*.hea")):
    base = os.path.splitext(hea)[0]
    r = wfdb.rdrecord(base, physical=True)
    icp = r.p_signal[:, r.sig_name.index("ICP")]
    rows.append((base, round(len(icp) / r.fs / 3600, 1),
                 round(float(np.nanpercentile(icp, 95)), 1)))
print(rows)

这三段合起来是一条完整链路:下载、校验、解析、换算、取段、绘图、全库摘要。后面的分析全部在这条链路上扩展。

9.3 引用方式

使用时必须引用原始论文,官方页面给的格式是:Kim N, Krasner A, Kosinski C, Wininger M, Qadri M, Kappus Z, Danish S, Craelius W. Trending autoregulatory indices during treatment for traumatic brain injury. Journal of Clinical Monitoring and Computing, 2016, 30(6): 821–831,DOI 为 10.1007/s10877-015-9779-3。

除论文外,PhysioNet 要求同时引用平台的通用引用,并在数据可获得性声明里写明版本号与 DOI。本库的版本 DOI 是 10.13026/C24G6F。

ODC-BY 1.0 的许可要求很宽松:允许商用、允许再分发、允许修改,条件是注明来源。对于二次加工后的衍生数据,同样需要保留署名。

§10 AI 使用声明

项目 说明
数据性质 真实临床记录回填,非合成数据
患者识别 仅以编号标识,公开文件内无姓名、住院号、日期
二次标识风险 文件未含日期与地点,重识别风险较低
伦理审查 官方页面未披露伦理批件编号
知情同意 官方页面未披露知情同意形式
用途限制 许可未对用途做额外限制,但临床决策不可直接依赖其结果
AI 训练适用性 结构上可用于流水线验证,规模上不足以作为训练来源
医学免责 本页所有数值均来自官方页面或原论文摘要,不构成临床建议

常见误读(避坑清单)

常见说法 实际 证据
它有二十九名患者的数据 公开文件只有十三条 记录清单 RECORDS 共十三行
它只有创伤患者 诊断中含脑血管病与蛛网膜下腔出血 头文件诊断行出现 CVA、SAH
它有颅内高压事件标注 目录内无注释文件、无事件表 目录只有 .hea 与 .dat
它适合训练颅内压预测模型 患者级样本量两位数刚出头 记录数十三
采样率是五十赫兹就能做形态分析 二十五赫兹截止滤波在上游就切掉了高频 官方采集说明
颅内压通道存在就代表连续可用 部分患者只有间断脑室测压 charis9 头文件备注行
时长乘采样率就是有效时长 断开段仍写入采样点 charis9 的第二条备注
诊断字段可以直接当分类标签 缩写粒度不一,部分记录缺失 头文件患者信息行格式不统一
它和大型 ICU 波形库可以互换 规模、通道、采样率都差一个量级 两者官方页面
压力反应指数可以直接当临床指标 官方论文明确其在单例上预测分辨率不足 论文摘要的结论句

FAQ

Q1:CHARIS 到底有多少名患者?
公开库十三条记录,对应十三名患者。同一项目的论文摘要写明采集系统在十八个月里记录了二十九名颅脑创伤患者。两者是不同口径,差额的构成官方未说明。

Q2:它能不能直接用来训练颅内压预测模型?
不适合做训练集的规模来源。十三条记录、每段数十到数百小时,参数化模型在患者层面会迅速过拟合。更合适的用法是流水线验证与已发表结论的复核。

Q3:为什么采样率只有五十赫兹?
因为采集目的在趋势而不在形态。模拟输出先经过二十五赫兹截止的隔离滤波,再以五十赫兹采样,刚好满足奈奎斯特条件。代价是波形细节被削弱,换来的是整段住院时间的小体积存档。

Q4:它有没有伦理批件或知情同意说明?
官方页面与论文摘要都没有披露这方面的信息。使用前若涉及再发表或衍生用途,应按所在机构的伦理要求自行判断。

Q5:单条记录有多长?
从四十小时到三百七十五小时不等。记录时长跟着住院时长走,不是固定切片。

Q6:颅内压通道出现长段平坦该怎么办?
先查该记录头文件是否有间断采集的备注,再看平坦段的实际波动幅度。若确认是间断测值或脱落,应在切窗时排除这些时段,而不是把平坦段当作生理状态。

Q7:能算出压力反应指数吗?
能,这是它被公开的主要目的之一。计算时需自选窗口长度与步长,并先剔除伪迹。论文里的自动事件探测器不在数据包内,参数也未公开。

Q8:为什么有记录的诊断是 CVA 而不是 TBI?
因为入组条件写的是「诊断为脑损伤」,范围覆盖了创伤之外的急性脑损伤类型。诊断字段记录的是病历上的简要结论,不是研究分组。

Q9:它和儿科颅内压库有什么区别?
主要为人群与来源:一个来自成人创伤中心,一个来自儿童医院;采样率也不同,前者五十赫兹,后者更高。两者可以互为外部对照,但两侧样本都小,比较的统计力有限。

Q10:能不能把它与其他 ICU 数据库的可疑患者记录关联?
不能。公开文件只有编号,没有日期、机构标识与住院号,无法与任何外部数据库做确定性关联。

Q11:使用许可有什么要求?
ODC-BY 1.0,允许商用与再分发,要求注明来源。除数据许可外,PhysioNet 还要求引用平台本身的通用文献。

Q12:有没有更新版本?
目录内文件的时间戳停在 2019 年 2 月,此前 2017 年为首次发布。信号内容自发布起未见变更记录。

术语表

术语 解释
颅内压(ICP) 颅腔内的压力,由脑组织、血液与脑脊液共同决定
动脉血压(ABP) 体循环动脉内的压力,这里是桡动脉置管的连续读数
颅脑创伤(TBI) 外力导致的脑组织损伤,本库的主要收治类型
压力反应指数(PRx) 颅内压与动脉血压在滑动窗口内的回归斜率
脑自动调节 脑血管在灌注压变化时维持血流稳定的能力
过度通气 通过增加呼吸频率降低动脉二氧化碳分压,从而收缩脑血管的手段
甘露醇 渗透性脱水剂,用于降低颅内压
脑室引流 在侧脑室放置导管,兼做引流与测压
脑实质探头 直接插入脑组织的微型压力传感器
颅内高压 颅内压持续升高,常用阈值是二十毫米汞柱
外科重症监护室(SICU) 收治需要外科干预的重症患者的病房
隔离放大 把患者侧电路与记录设备电气隔离,防止漏电
截止频率 低通滤波器开始衰减的频率点,这里是二十五赫兹
奈奎斯特条件 采样率需高于信号最高频率的两倍才能无失真重建
增益 把整数采样值换算成物理量的比例系数
基线 头文件中用于换算的偏移量
WFDB PhysioNet 长期使用的波形数据存储格式
头文件 描述通道、采样率、增益与注释的纯文本文件
交错存储 同一采样点的各通道数值首尾相接写入
伪迹 非生理来源的信号干扰,如运动、管路打折、电刀
零点校准 把压力传感器调至大气压为零的操作
区间事件 在一段时间内持续满足阈值的状态,区别于瞬时点事件
患者级划分 按患者而非按记录划分训练与测试,防止同源泄漏
外部验证 用未参与训练的数据评估模型,检验泛化
单中心偏倚 数据全部来自同一机构导致的代表性不足
再识别风险 去标识数据被重新对应到具体个人的可能性

附录 A:核心数字核对表

项 值 来源 来源层级
记录数 13 记录清单 RECORDS 官方文件
通道数 3 全部头文件首行 官方文件
采样率 50 Hz 全部头文件首行 官方文件
滤波截止 25 Hz 官方项目页 官方页面
未压缩体积 1.6 GB 官方项目页 官方页面
DOI 10.13026/C24G6F 官方项目页 官方页面
首次发布 2017-01-19 官方项目页 官方页面
校验和更新 2019-02-20 目录内文件时间 官方文件
压力分辨率 0.14 mmHg 官方项目页 官方页面
动态范围 ±500 mmHg 官方项目页 官方页面
研究队列 29 名 论文摘要 论文摘要
采集周期 18 个月 论文摘要 论文摘要
单条最长时长 约 375 小时 头文件采样点数折算 官方文件推算
许可 ODC-BY 1.0 官方项目页 官方页面
颅脑创伤外的诊断 SDH、SAH、ICH、CVA 头文件患者信息行 官方文件
伦理批件 官方未公布 — 未披露

附录 B:数字的来源分层

层级 数字 说明
官方页面 三通道、五十赫兹、二十五赫兹截止、一点六吉字节、0.14 毫米汞柱、±500 毫米汞柱、DOI、许可 来自 PhysioNet 项目页的说明文字
官方文件 十三条记录、采样点数、增益与基线、单位、诊断缩写、转归 来自头文件与记录清单的直接读取
论文摘要 二十九名患者、十八个月、二十毫米汞柱阈值、甘露醇与过度通气处置 来自原论文摘要
官方未公布 每条记录的确切起止日期、患者年龄分布、诊断计数、事件总数、伦理批件 页面上没有这些信息
不采用 任何自行统计的百分位、直方图与交叉表 本页不做分布审计

附录 C:完整参考文献

  1. Kim N, Krasner A, Kosinski C, Wininger M, Qadri M, Kappus Z, Danish S, Craelius W. Trending autoregulatory indices during treatment for traumatic brain injury. Journal of Clinical Monitoring and Computing, 2016, 30(6): 821–831. DOI: 10.1007/s10877-015-9779-3.
  2. PhysioNet. CHARIS database, version 1.0.0. 2017-01-19. DOI: 10.13026/C24G6F.
  3. Pollard T, Moody BE, Lehman LH, Gow BJ, Fernandes C, Xie C, Johnson A, Mark RG, Heldt T. PhysioNet as a global platform for biomedical research. Nature Health, 2026: 792–795. DOI: 10.1038/s44360-026-00096-z.
  4. Open Data Commons. Attribution License v1.0. https://opendatacommons.org/licenses/by/1-0/
  5. Moody GB, Mark RG. The impact of the MIT-BIH Arrhythmia Database. IEEE Engineering in Medicine and Biology Magazine, 2001, 20(3): 45–50.

附录 D:任务代码

把「下载、解析、筛有效段、切事件、算指数、导出」六个环节写成一条可复用的脚本骨架:

#-- 一条从原始文件到指数序列的完整通路
import os, glob, re
import numpy as np
import wfdb

def load_record(path):
    rec = wfdb.rdrecord(path, physical=True)
    meta = " ".join(rec.comments)
    return rec, meta

def icp_valid_mask(icp, fs, win_sec=30, flat_std=0.05, jump_mmhg=20.0):
    win = int(fs * win_sec)
    if len(icp) < win:
        return np.zeros(len(icp), dtype=bool)
    sd = np.array([icp[i:i + win].std() for i in range(0, len(icp) - win, win)])
    flat = np.repeat(sd < flat_std, win)
    flat = np.pad(flat, (0, len(icp) - len(flat)), constant_values=False)
    jump = np.abs(np.diff(icp, prepend=icp[0])) > jump_mmhg
    return ~(flat | jump)

def prx_series(abp, icp, valid, fs, win_sec=300, step_sec=60, min_valid=0.8):
    w, s = int(win_sec * fs), int(step_sec * fs)
    out = []
    for st in range(0, len(icp) - w, s):
        v = valid[st:st + w]
        #-- 窗口内有效采样比例不够就放弃
        if v.mean() < min_valid:
            continue
        x, y = abp[st:st + w][v], icp[st:st + w][v]
        if x.std() < 1e-6 or y.std() < 1e-6:
            continue
        out.append((round((st + w / 2) / fs / 60.0, 1), float(np.polyfit(x, y, 1)[0])))
    return out

if __name__ == "__main__":
    for path in sorted(glob.glob("charisdb/charis*.hea")):
        rec, meta = load_record(path[:-4])
        fs = rec.fs
        abp = rec.p_signal[:, rec.sig_name.index("ABP")]
        icp = rec.p_signal[:, rec.sig_name.index("ICP")]
        mask = icp_valid_mask(icp, fs)
        series = prx_series(abp, icp, mask, fs)
        #-- 结果写成两列纯文本,便于后续直接画图
        with open(path[:-4] + "_prx.tsv", "w", encoding="utf-8") as f:
            f.write("minute\tprx\n")
            for t, v in series:
                f.write(f"{t}\t{round(v, 4)}\n")
        print(os.path.basename(path), "有效比例", round(float(mask.mean()), 3),
              "窗口数", len(series))

这个骨架有两点值得注意。第一,有效掩码是在切窗之前算的,且窗口内有效比例不够就跳过,这能避免间断段进入指数序列。第二,参数全部暴露在函数签名里,改动任何一项都会写进文件,便于复现。

#-- 批量跑,再汇总每个记录的有效比例
python3 run_prx.py
awk -F'\t' 'NR>1{n++} END{print "窗口总数", n}' charisdb/charis9_prx.tsv

附录 E:如果只记五件事

  1. 它是什么:PhysioNet 上的重症颅脑损伤床旁监护波形库,三通道心电、动脉血压、颅内压同步记录。
  2. 有多大:公开十三条记录、十三名患者,未压缩一点六吉字节,单条四十到三百七十五小时。
  3. 怎么存:WFDB 格式,五十赫兹,十六位整数,头文件附年龄、性别、诊断、转归四项。
  4. 边界在哪:单中心、无标注、无用药记录、部分颅内压只有间断测值、诊断谱含创伤之外的脑血管病。
  5. 该怎么用:当机制材料与流水线验证样本,不当训练集的规模来源。

编辑说明

核验时间 2026 年 10 月 28 日。核验方式为直接访问 PhysioNet 项目页与版本目录,逐条读取十三个头文件与记录清单,并调取原论文的 PubMed 摘要比对队列规模。

本页不包含任何自行统计的分布数字。凡涉及人数、时长、体积、采样率的数值,均来自官方页面说明、官方文件直接读取或论文摘要三处之一,来源层级见附录 B。

未覆盖的内容包括:每条记录的实际起止日期、患者年龄与性别的聚合分布、颅内高压事件的官方计数、伦理批件的编号与形式。这些在公开材料里都没有,因此没有填写。


相关数据集导航

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

  • pics — 共享标签:生理信号 / 心电信号 / 重症监护 / 时序数据
  • veterinary-vitals-anesthesia — 共享标签:生理信号 / 心电信号 / 重症监护 / 时序数据
  • mimic-iv-waveform-legacy — 共享标签:生理信号 / 重症监护 / 时序数据
  • cinc-2015 — 共享标签:生理信号 / 心电信号 / 重症监护 / 时序数据
  • mover — 共享标签:生理信号 / 心电信号 / 重症监护 / 时序数据
  • mimic-iv-ext-ecg-glucose — 共享标签:生理信号 / 心电信号 / 重症监护 / 时序数据
  • mghdb — 共享标签:生理信号 / 心电信号 / 重症监护
  • ob1db — 共享标签:生理信号 / 心电信号 / 时序数据
  • cpsc — 共享标签:生理信号 / 心电信号 / 时序数据
  • sicdb — 共享标签:生理信号 / 重症监护 / 时序数据

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

返回 AI-Ready 数据集