为什么SciPy的interp1d会花费一分钟来构建插补器?

时间:2018-03-22 11:30:06

标签: python-2.7 numpy scipy interpolation

我想在1d内插入一系列浮点数(或矢量)的四元组或立方体,其中long可以是1E + 05或1E + 06(或更多)。出于某种原因,SciPi方便的interp1d()准备内插器的时间开销对于二次和三次样条曲线几乎都是n ^ 3,需要花费一分钟几千点。

根据评论here(我将删除的一个问题,我暂时将其保留在那里以进行评论访问)在其他计算机上需要一毫秒,所以这里显然存在病态错误。

我的安装有点旧,但是SciPy的.interp1d()已经存在了很长一段时间。

np.__version__    '1.13.0'
scipy.__version__ '0.17.0'

我可以做些什么来试图找出这种令人难以置信的插值慢度?

time for interpolator

import time
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import interp1d

times = []
for n in np.logspace(1, 3.5, 6).astype(int):
    x = np.arange(n, dtype=float)
    y = np.vstack((np.cos(x), np.sin(x)))
    start = time.clock()
    bob = interp1d(x, y, kind='quadratic', assume_sorted=True)
    times.append((n, time.clock() - start))

n, tim = zip(*times)

plt.figure()
plt.plot(n, tim)
plt.xscale('log')
plt.yscale('log')
plt.show()

1 个答案:

答案 0 :(得分:3)

简短回答:更新你的scipy安装。

更长的答案:0.19之前,interp1d基于splmake,它使用带有完整矩阵的线性代数。在scipy 0.19中,它被重构为使用带状线性代数。结果,(下面是scipy 0.19.1)

In [14]: rndm = np.random.RandomState(1234) 

In [15]: for n in [100, 1000, 10000, int(1e6)]:
    ...:     x = np.sort(rndm.uniform(size=n))
    ...:     y = np.sin(x)
    ...:     %timeit interp1d(x, y, kind='quadratic', assume_sorted=True)
    ...:     
    ...:     

244 µs ± 4.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
422 µs ± 4.21 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
2.17 ms ± 50.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
227 ms ± 4.45 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [16]: 

In [16]: for n in [100, 1000, 10000, int(1e6)]:
    ...:     x = np.sort(rndm.uniform(size=n))
    ...:     y = np.sin(x)
    ...:     %timeit interp1d(x, y, kind='cubic', assume_sorted=True)
    ...:     
    ...:     

241 µs ± 4.67 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
462 µs ± 4.92 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
2.64 ms ± 37.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
276 ms ± 1.91 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

你的其他选项是CubicSpline如果你想要特殊的三次样条(这是scipy 0.18中的新内容)或make_interp_spline如果你也想要二次样条(scipy 0.19中的新内容;这就是{{1}在引擎盖下使用。)