You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Colab运行Python脚本处理EDF文件时RAM不足崩溃如何解决

问题核心原因
  • 你对sigbufs和t做的切片默认是视图而非独立副本,append到dataset的切片会一直持有原始大数组的内存引用,导致你del sigbufs后原始数组的内存依然无法被回收
  • 你一次性读取了整个EDF文件的全部信号数据,中间产生的超大数组远大于你实际需要的片段,无意义占用大量内存
  • 所有截取结果都攒在dataset列表里全程持有,123份结果累计占用的内存超过阈值
解决方案
  1. 切片强制生成独立副本,切断对原始大数组的引用
    修改append行代码为:

    dataset.append([t[start:end].copy(), sigbufs[:,start:end].copy()])
    

    新增对临时变量t的清理,循环末尾补:

    del sigbufs, f, t
    gc.collect(generation=2)
    
  2. 直接读取EDF的指定区间,避免加载全量数据
    pyedflib的readSignal支持指定起始、结束样本位置,不需要先读整个文件再切片,从根源减少内存占用:

    # 预先计算需要读取的样本范围
    target_start = detail['seizure start'][i] * 256 - 100
    target_end = detail['seizure end'][i] * 256 + 100
    read_len = target_end - target_start
    
    f = pyedflib.EdfReader(name)
    n = f.signals_in_file
    # 直接创建目标长度的数组,不需要存全量信号
    sig_segment = np.zeros((n, read_len))
    for j in np.arange(n):
        # 只读需要的区间
        sig_segment[j, :] = f.readSignal(j, start=target_start, n=read_len)
    t_segment = np.linspace(target_start/fs, target_end/fs, read_len)
    f.close()
    # 直接append读取好的片段,不需要额外切片
    dataset.append([t_segment, sig_segment])
    print(f"completed run {i} out of {length}")
    del sig_segment, f, t_segment
    gc.collect(generation=2)
    
  3. 分批次持久化,不要攒全量结果在内存
    每处理20条就把当前批次的结果写入到pickle文件,清空内存里的dataset列表再处理下一批,最终需要用的时候再合并多个批次的文件即可:

    batch_size = 20
    for batch_idx in range(0, length, batch_size):
        dataset = []
        # 处理当前批次的20条数据
        for i in range(batch_idx, min(batch_idx + batch_size, length)):
            # 这里放上面修改后的单条处理逻辑
            ...
        # 批次处理完直接写入本地
        with open(f"dataset_batch_{batch_idx}.pkl",'wb') as fp:
            pickle.dump(dataset, fp)
        del dataset
        gc.collect(generation=2)
    

内容的提问来源于stack exchange,提问作者NeuroEng

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 16:54:02