16×90000信号数组逐行匹配滤波:替代scipy.convolve2d高效无循环方案
高效实现逐行信号互相关(无循环)
你之前用scipy.signal.convolve2d的核心问题是:这个函数是做二维卷积,会对整个矩阵的行和列进行交叉运算,完全超出了“逐行对应互相关”的需求,自然效率极低。下面给出两种无循环的高效实现方案:
方案一:用Scipy原生函数直接指定轴运算
scipy.signal.correlate支持通过axis参数指定运算维度,直接实现逐行互相关,内部做了性能优化,是最简单高效的方式:
from scipy import signal import numpy as np A = np.random.rand(16, 90000) # 16条长度90000的信号 B = np.random.rand(16, 90000) # 指定axis=1,对每行执行互相关,mode='same'匹配需求 corr = signal.correlate(A, B, mode='same', axis=1)
该方法会自动选择最优运算逻辑(FFT或直接卷积),避免了不必要的行列间运算,速度比convolve2d快几个数量级。
方案二:基于FFT手动实现(适合自定义需求)
如果需要更精细的控制,可以利用FFT卷积定理实现逐行互相关,借助numpy的广播和轴参数实现无循环:
import numpy as np A = np.random.rand(16, 90000) B = np.random.rand(16, 90000) signal_len = A.shape[1] # 逐行执行FFT fft_A = np.fft.rfft(A, axis=1) # 对B的FFT结果取共轭(互相关等价于A与翻转B的卷积,FFT域对应相乘共轭) fft_B_conj = np.conj(np.fft.rfft(B, axis=1)) # 相乘后逆FFT得到全长度互相关结果 full_corr = np.fft.irfft(fft_A * fft_B_conj, axis=1) # 截取到mode='same'的长度(取中间signal_len个点) start = (full_corr.shape[1] - signal_len) // 2 corr_same = full_corr[:, start:start + signal_len]
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

