我正在编写自己的脚本来计算两个信号之间的关系。因此,我使用mlab.csd和mlab.psd函数来计算信号的CSD和PSD。
我的数组x的形状为(120,68,68,815)。我的脚本运行了几分钟,而此功能正是这么长时间的热点。
有人知道我应该怎么做吗?我对脚本性能的提高并不熟悉。谢谢!
# to read the list of stcs for all the epochs
with open('/home/daniel/Dropbox/F[...]', 'rb') as f:
label_ts = pickle.load(f)
x = np.asarray(label_ts)
nfft = 512
n_freqs = nfft/2+1
n_epochs = len(x) # in this case there are 120 epochs
channels = 68
sfreq = 1017.25
def compute_mean_psd_csd(x, n_epochs, nfft, sfreq):
'''Computes mean of PSD and CSD for signals.'''
Rxy = np.zeros((n_epochs, channels, channels, n_freqs), dtype=complex)
Rxx = np.zeros((n_epochs, channels, channels, n_freqs))
Ryy = np.zeros((n_epochs, channels, channels, n_freqs))
for i in xrange(0, n_epochs):
print('computing connectivity for epoch %s'%(i+1))
for j in xrange(0, channels):
for k in xrange(0, channels):
Rxy[i,j,k], freqs = mlab.csd(x[j], x[k], NFFT=nfft, Fs=sfreq)
Rxx[i,j,k], _____ = mlab.psd(x[j], NFFT=nfft, Fs=sfreq)
Ryy[i,j,k], _____ = mlab.psd(x[k], NFFT=nfft, Fs=sfreq)
Rxy_mean = np.mean(Rxy, axis=0, dtype=np.float32)
Rxx_mean = np.mean(Rxx, axis=0, dtype=np.float32)
Ryy_mean = np.mean(Ryy, axis=0, dtype=np.float32)
return freqs, Rxy, Rxy_mean, np.real(Rxx_mean), np.real(Ryy_mean)
最佳答案
如果csd
和psd
方法的计算量很大,那可能会有所帮助。有可能您可能只是缓存先前调用的结果并获取它,而不是多次计算。
看来,您将有120 * 68 * 68 = 591872
个周期。
对于psd计算,如果方法仅取决于一个参数,则应该可以毫无问题地缓存值。
将值存储在x[j]
或x[k]
的字典中,以检查该值是否存在。如果该值不存在,请对其进行计算并存储。如果该值存在,则只需跳过该值并重新使用该值即可。
if x[j] not in cache_psd:
cache_psd[x[j]], ____ = mlab.psd(x[j], NFFT=nfft, Fs=sfreq)
Rxx[i,j,k] = cache_psd[x[j]]
if x[k] not in cache_psd:
cache_psd[x[k]], ____ = mlab.psd(x[k], NFFT=nfft, Fs=sfreq)
Ryy[i,j,k] = cache_psd[x[k]]
您可以使用
csd
方法执行相同的操作。我对此不太了解,无法多说。如果参数的顺序无关紧要,则可以按排序的顺序存储两个参数,以防止重复的内容,例如2, 1
和1, 2
。仅当内存访问时间小于计算时间和存储时间时,使用缓存才可以使代码更快。可以使用带有
memoization
的模块轻松添加此修复程序。这是有关记忆的文章,供进一步阅读:
http://www.python-course.eu/python3_memoization.php