我的4D结构包含形状为class HTMLRenderer(QWebEngineView):
def __init__(self):
super(HTMLRenderer, self).__init__()
self.setHtml('<div>Try HTML</div>')
self.show()
这表示3432个数据试验,其中每个试验包含512个电极的512个时间样本
对于每个试验,我想用某些滤波器参数过滤每个电极,这会产生一个新的2D (3432,1,30,512)
滤波阵列。然后,我想沿着4D结构的轴1堆叠它们。
目前,我正在迭代每个试验,然后是每个电极,过滤信号并将所有内容重新插入4D:
(30,512)
迭代试验和电极非常慢(完成整个循环需要大约2个小时)。是否有更有效的方法将此过滤器应用于所有电极/试验?
我一直试图找到一种方法将滤镜应用于2D,所以我不需要迭代电极,但却找不到任何东西。
编辑:
这是使用from scipy import signal
NUM_CHANS = 30
NUM_TIMESTAMPS = 512
FREQ_BANDS = ((0.1, 3), (4, 7), (8, 13), (16, 31))
all_data = np.reshape(all_data, (-1, 1, NUM_CHANS, NUM_TIMESTAMPS)) # (3432,1,30,512)
for i in range(all_data.shape[0]):
num_band = 1
for band in FREQ_BANDS:
lower = float(band[0])/(SAMPLE_RATE/2)
upper = float(band[1])/(SAMPLE_RATE/2)
# Design new filter for the current frequency band
b, a = signal.butter(2, [lower, upper], 'bandpass')
temp_trial = np.zeros((NUM_CHANS, NUM_TIMESTAMPS))
for ch in range(NUM_CHANS):
# Filter the current electrode
output_signal = signal.filtfilt(b, a, all_data[i,0,ch,:])
temp_trial[ch,:] = output_signal
# Insert temp_trial (2D) into all_data (4D) along axis 1
num_band += 1
轴参数的正确方法吗?
filtfilt
答案 0 :(得分:1)
这是一项可能会改善效果的变化。 filtfilt
有一个axis参数,它允许您沿着n维数组的轴应用相同的1-d滤镜。您可以替换此代码
temp_trial = np.zeros((NUM_CHANS, NUM_TIMESTAMPS))
for ch in range(NUM_CHANS):
# Filter the current electrode
output_signal = signal.filtfilt(b, a, all_data[i,0,ch,:])
temp_trial[ch,:] = output_signal
与
temp_trial = signal.filtfilt(b, a, all_data[i,0,:,:], axis=1)
由于默认axis
为axis=-1
,如果您愿意,可以省略轴参数:
temp_trial = signal.filtfilt(b, a, all_data[i,0,:,:])
通过重新排列外环,你可以做得更好。使“band”循环成外循环。然后,对于每个频段,您可以将filtfilt
一次应用于三维数组all_data[:, 0, :, :]
。
这样的事情:
shp = all_data.shape
# This assumes `all_data` has shape (3432,1,30,512), but I don't
# think you need that trivial extra dimension in there if you
# preallocate `filtered_data` like I am doing here.
filtered_data = np.empty(shp[0:1] + (len(FREQ_BANDS),) + shp[2:])
for k, band in enumerate(FREQ_BANDS):
lower = float(band[0])/(SAMPLE_RATE/2)
upper = float(band[1])/(SAMPLE_RATE/2)
# Design new filter for the current frequency band
b, a = signal.butter(2, [lower, upper], 'bandpass')
filtered_data[:, k, :, :] = filtfilt(b, a, all_data[:,0,:,:])
这不包括all_data
中的原始filtered_data
。如果您需要,请在创建len(FREQ_BANDS)+1
的{{1}}调用中使用np.empty()
,设置filtered_data
,然后使用filtered_data[:,0,:,:] = all_data
代替k+1
赋值语句,用于保存k
调用的结果。