jus*_*hie 16 python numpy cython
我在我的python程序中使用cython进行相关计算.我有两个音频数据集,我需要知道它们之间的时差.基于开始时间切割第二组,然后滑过第一组.有两个for循环:一个滑动集合,内循环计算该点的相关性.这种方法效果很好,而且足够准确.
问题是使用纯python这需要一分多钟.使用我的cython代码,大约需要17秒.这仍然太多了.您是否有任何提示如何加速此代码:
import numpy as np
cimport numpy as np
cimport cython
FTYPE = np.float
ctypedef np.float_t FTYPE_t
@cython.boundscheck(False)
def delay(np.ndarray[FTYPE_t, ndim=1] f, np.ndarray[FTYPE_t, ndim=1] g):
cdef int size1 = f.shape[0]
cdef int size2 = g.shape[0]
cdef int max_correlation = 0
cdef int delay = 0
cdef int current_correlation, i, j
# Move second data set frame by frame
for i in range(0, size1 - size2):
current_correlation = 0
# Calculate correlation at that point
for j in range(size2):
current_correlation += f[<unsigned int>(i+j)] * g[j]
# Check if current correlation is highest so far
if current_correlation > max_correlation:
max_correlation = current_correlation
delay = i
return delay
Run Code Online (Sandbox Code Playgroud)
tom*_*m10 37
编辑:
现在scipy.signal.fftconvolve,这将是我在下面描述的基于FFT的卷积方法的首选方法.我会留下原来的答案来解释速度问题,但在实践中使用scipy.signal.fftconvolve.
原始答案:
使用FFT和卷积定理可以将问题从O(n ^ 2)转换为O(n log n),从而显着提高速度.这对于像您这样的长数据集特别有用,并且可以根据长度提供1000秒或更多的速度增益.这也很容易:只需对产品进行FFT信号,乘法和逆FFT.numpy.correlate在互相关例程中不使用FFT方法,并且最好与非常小的内核一起使用.
这是一个例子
from timeit import Timer
from numpy import *
times = arange(0, 100, .001)
xdata = 1.*sin(2*pi*1.*times) + .5*sin(2*pi*1.1*times + 1.)
ydata = .5*sin(2*pi*1.1*times)
def xcorr(x, y):
return correlate(x, y, mode='same')
def fftxcorr(x, y):
fx, fy = fft.fft(x), fft.fft(y[::-1])
fxfy = fx*fy
xy = fft.ifft(fxfy)
return xy
if __name__ == "__main__":
N = 10
t = Timer("xcorr(xdata, ydata)", "from __main__ import xcorr, xdata, ydata")
print 'xcorr', t.timeit(number=N)/N
t = Timer("fftxcorr(xdata, ydata)", "from __main__ import fftxcorr, xdata, ydata")
print 'fftxcorr', t.timeit(number=N)/N
Run Code Online (Sandbox Code Playgroud)
这给出了每个周期的运行时间(以秒为单位,对于10000个长波形)
xcorr 34.3761689901
fftxcorr 0.0768054962158
Run Code Online (Sandbox Code Playgroud)
很明显fftxcorr方法要快得多.
如果你绘制出结果,你会发现它们在零时移附近非常相似.但请注意,随着距离越来越远,xcorr将减少,fftxcorr将不会减少.这是因为当波形移位时,如何处理波形中不重叠的部分,这有点模棱两可.xcorr将其视为零,并且FFT将波形视为周期性的,但如果它是一个问题,则可以通过零填充来修复.
| 归档时间: |
|
| 查看次数: |
4817 次 |
| 最近记录: |