我在我的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
编辑:
现在有scipy.signal.fftconvolve
一种方法将成为我在下面描述的基于FFT的卷积方法的首选方法。我将保留原始答案以解释速度问题,但实际上使用scipy.signal.fftconvolve
。
原始答案:
通过将 FFT 问题从O(n ^ 2)转换为O(n log n),使用 FFT 和
卷积定理
可以显着提高速度。这对于像您这样的长数据集特别有用,并且视长度而定,可以使速度提高1000倍甚至更多。这也很容易做到:只需对两个信号进行FFT,对乘积进行逆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
给出每个周期的运行时间(以秒为单位,表示10,000个长波形)
xcorr 34.3761689901
fftxcorr 0.0768054962158
很明显fftxcorr方法要快得多。
如果将结果绘制出来,您会发现它们在零时移附近非常相似。但是请注意,随着距离的增加,xcorr会减少,而fftxcorr不会。这是因为处理波形移位时不重叠的波形部分有点模棱两可。xcorr将其视为零,而FFT将波形视为周期性,但如果出现问题,则可以通过零填充来解决。
问题内容: 我有一个分析代码,使用numpy进行了一些繁重的数值运算。出于好奇,尝试使用cython对其进行几乎没有任何更改的编译,然后使用numpy部分的循环将其重写。 令我惊讶的是,基于循环的代码要快得多(8倍)。我无法发布完整的代码,但是我将一个非常简单的不相关的计算放在一起,显示出相似的行为(尽管时间差异不是很大): 版本1(无cython) 版本2(使用cython构建模块) 版本3(使
问题内容: 在Cython文档的教程中,有numpy模块的cimport和import语句: 我发现此约定在numpy / cython用户中非常流行。 这看起来很奇怪的我,因为他们 都 命名为 NP 。在代码的哪一部分中使用了导入/导入的np?为什么cython编译器不会混淆它们? 问题答案: 可以访问 C 函数或属性,甚至可以访问下面的子模块 可以访问下方的 Python 函数或属性或子模块。
问题内容: 具有以下假设代码: 有什么方法可以将列表转换为c数组吗? 问题答案: 尝试以下代码。以下代码中的函数是您想要的。
本文向大家介绍用Cython加速Python到“起飞”(推荐),包括了用Cython加速Python到“起飞”(推荐)的使用技巧和注意事项,需要的朋友参考一下 事先声明,标题没有把“Python”错打成“Cython”,因为要讲的就是名为“Cython”的东西。 Cython是让Python脚本支持C语言扩展的编译器,Cython能够将Python+C混合编码的.pyx脚本转换为C代码,主要用于优
准确说Cython是单独的一门语言,专门用来写在Python里面import用的扩展库。实际上Cython的语法基本上跟Python一致,而Cython有专门的“编译器”先将 Cython代码转变成C(自动加入了一大堆的C-Python API),然后使用C编译器编译出最终的Python可调用的模块。
问题内容: 我正在使用Cython或NumPy对一维数组中的每个元素求和。当对 整数 求和时,Cython快〜20%。当对 浮点 求和时,Cython慢 约2.5倍。以下是使用的两个简单功能。 时机 创建两个数组,每个数组包含一百万个元素: 附加点 NumPy在浮点数方面的表现(相当大的优势)甚至超过了自己的整数和。 的性能差异与和指令缺失相同。为什么? 将整数numpy数组转换为C指针()可将性