Scipy的相关功能很慢

时间:2015-06-03 12:20:02

标签: 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会使用速度慢得多的实现吗?

Speed comparison 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()

1 个答案:

答案 0 :(得分:3)

根据文档,numpy.correlate是为1D数组设计的,而scipy.correlate可以接受ND数组。

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

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