Scipy的相关功能很慢

Chr*_*ris 8 python numpy scipy

我已经比较了使用numpy/scipy卷积/关联两个信号的不同方法.事实证明,速度存在巨大差异.我比较了以下方法:

  • 与numpy包相关联(np.correlate in plot)
  • 与scipy.signal包相关联(sps.correlate in plot)
  • 来自scipy.signal的fftconvolve(sps.fftconvolve in plot)

现在我当然明白fftconvolve与其他两个函数之间存在很大差异.我不明白为什么sps.correlate比np.correlate慢得多.有人知道为什么scipy会使用速度慢得多的实现吗?

速度比较http://i62.tinypic.com/ofrqxc.png

为了完整性,以下是生成图的代码:

import time

import numpy as np
import scipy.signal as sps

from matplotlib import pyplot as plt


if __name__ == '__main__':

    a = 10**(np.arange(10)/2)
    print(a)

    results = {}
    results['np.correlate'] = np.zeros(len(a))
    results['sps.correlate'] = np.zeros(len(a))
    results['sps.fftconvolve'] = np.zeros(len(a))

    ii = 0
    for length in a:

        sig = np.random.rand(length)

        t0 = time.clock()
        for jj in range(3):
            np.correlate(sig, sig, 'full')
        t1 = time.clock()
        elapsed = (t1-t0)/3

        results['np.correlate'][ii] = elapsed

        t0 = time.clock()
        for jj in range(3):
            sps.correlate(sig, sig, 'full')
        t1 = time.clock()
        elapsed = (t1-t0)/3

        results['sps.correlate'][ii] = elapsed

        t0 = time.clock()
        for jj in range(3):
            sps.fftconvolve(sig, sig, 'full')
        t1 = time.clock()
        elapsed = (t1-t0)/3

        results['sps.fftconvolve'][ii] = elapsed

        ii += 1

    ax = plt.figure()
    plt.loglog(a, results['np.correlate'], label='np.correlate')
    plt.loglog(a, results['sps.correlate'], label='sps.correlate')
    plt.loglog(a, results['sps.fftconvolve'], label='sps.fftconvolve')
    plt.xlabel('Signal length')
    plt.ylabel('Elapsed time in seconds')

    plt.legend()
    plt.grid()

    plt.show()
Run Code Online (Sandbox Code Playgroud)

rth*_*rth 4

根据文档,numpy.correlate它是为一维阵列设计的,同时scipy.correlate可以接受ND阵列。

scipy 实现更通用,因此更复杂,似乎确实会产生额外的计算开销。您可以比较numpyscipy实现之间的 C 代码。

另一个区别可能是,例如,现代处理器上的编译器可以更好地对 numpy 实现进行矢量化,等等。