单段代码可运行,放入for循环后处理index=29948时报错求助
问题排查:批量处理EEG数据时crop函数报错
可正常执行的单样本代码
raw = read_bdf(path='data_original/', subject='s01.bdf') raw.resample(sfreq=128, verbose=False) indices = get_indices_where_video_start(raw) index = indices[1] # 29948 eeg = ['Fp1', 'Fp2'] raw.pick_channels(eeg) raw = crop(raw, index) # << 此处处理index=29948正常
批量处理代码(出现报错)
subjects = get_subjects(path) # 返回目标文件夹内的所有文件名 for subject in subjects: raw = read_bdf(path='data_original/', subject=subject) raw.resample(sfreq=128, verbose=False) indices = get_indices_where_video_start(raw) for index in indices: eeg = ['Fp1', 'Fp2'] raw.pick_channels(eeg) cropped_raw = crop(raw, index) # 处理index=29948时报错
报错信息
ValueError: tmax (293.96875) must be less than or equal to the max time (60.0000 s)
crop函数定义
def crop(raw: mne.io.Raw, index_trial: int) -> mne.io.Raw: sample_rate = get_sample_rate(raw) min1 = sample_rate * 60 tmin = index_trial / sample_rate tmax = (index_trial + min1) / sample_rate cropped_raw = raw.crop(tmin=tmin, tmax=tmax) return cropped_raw
问题原因
核心问题是批量循环中重复修改了同一个raw对象:
- 单样本代码里,
raw.pick_channels(eeg)只执行一次,操作的是完整时长的原始数据。 - 批量代码中,第一次处理
index=16905时,raw.pick_channels(eeg)已经把原始数据裁剪成仅含指定通道的版本,但后续循环处理index=29948时,再次调用raw.pick_channels(eeg),此时的raw已经是之前裁剪后的短时长数据(仅60秒),而index=29948对应的时间点远超过这个时长,导致tmax计算后超出数据最大时间范围,触发报错。
解决方案
修改批量代码,确保每次循环处理不同index时,操作的是原始完整数据的副本,而非被修改后的raw对象:
方案一:提前创建完整数据副本
subjects = get_subjects(path) # 返回目标文件夹内的所有文件名 for subject in subjects: raw = read_bdf(path='data_original/', subject=subject) raw.resample(sfreq=128, verbose=False) # 提前创建原始数据的副本并完成通道选择 raw_full = raw.copy() eeg = ['Fp1', 'Fp2'] raw_full.pick_channels(eeg) indices = get_indices_where_video_start(raw) for index in indices: # 每次循环使用完整的通道选择后的数据副本进行裁剪 cropped_raw = crop(raw_full.copy(), index)
方案二:每次循环重新基于原始数据创建子集
subjects = get_subjects(path) # 返回目标文件夹内的所有文件名 for subject in subjects: raw = read_bdf(path='data_original/', subject=subject) raw.resample(sfreq=128, verbose=False) indices = get_indices_where_video_start(raw) eeg = ['Fp1', 'Fp2'] for index in indices: # 每次循环基于原始raw创建副本并选择通道 raw_subset = raw.copy().pick_channels(eeg) cropped_raw = crop(raw_subset, index)
内容的提问来源于stack exchange,提问作者tail
相关产品推荐
相关产品推荐

