Python 2.7 为什么SciPy';s interp1d构建插值器需要一分钟吗?

Python 2.7 为什么SciPy';s interp1d构建插值器需要一分钟吗?,python-2.7,numpy,scipy,interpolation,Python 2.7,Numpy,Scipy,Interpolation,我想在1d中四元或立方体插值一长串浮点(或向量),其中long可以是1E+05或1E+06(或更多)。出于某种原因,SciPi方便的interp1d()准备插值器的时间开销对于二次和三次样条曲线几乎都是n^3,对于几千个点需要一分钟 根据评论(我将删除一个问题,我暂时将其保留在那里以供评论访问),在其他计算机上需要一毫秒的时间,因此这里显然存在病态错误 我的安装有点旧,但是SciPy的.interp1d()已经存在了很长一段时间 np.__version__ '1.13.0' scipy.

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

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

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

np.__version__    '1.13.0'
scipy.__version__ '0.17.0'
我该怎么做才能算出插值的速度如此之慢


简短回答:更新您的scipy安装

更详细的回答:在0.19之前,
interp1d
是基于
splmake
的,它使用线性代数和完整矩阵。在scipy 0.19中,它被重构为使用带状线性代数。因此,(以下为scipy 0.19.1)


如果您特别想要三次样条曲线(这在scipy 0.18中是新的),那么您的其他选项是
CubicSpline
;如果您还想要二次样条曲线(在scipy 0.19中是新的;这是
interp1d
在引擎盖下使用的内容)。

简短回答:更新您的scipy安装

更详细的回答:在0.19之前,
interp1d
是基于
splmake
的,它使用线性代数和完整矩阵。在scipy 0.19中,它被重构为使用带状线性代数。因此,(以下为scipy 0.19.1)


如果您特别想要三次样条曲线(这在scipy 0.18中是新的),您的其他选项是
CubicSpline
,如果您还想要二次样条曲线(在scipy 0.19中是新的;这是
interp1d
在引擎盖下使用的)。

尝试使用较新的scipy,=>0.19应该更快。是的,对于0.19,请说
scipy.interpolate
改进。@kazemakase谢谢。当我可以的时候,我会研究更新scipy,但是我看到的速度实在是太不合理了,甚至在一次失败之前都不可能是正确的“改进。如果我选择10万分,就需要几天或几周的时间。看来一定是出了什么事。但我会尽快尝试更新。@kazemakase你说得对!看到了吗,这是在0.19完全重构的“改进”是一种轻描淡写的说法。尝试使用较新的scipy,=>0.19应该更快。是的,对于0.19来说,应该说
scipy.interpolate
改进。@kazemakase谢谢。当我可以的时候,我会研究更新scipy,但是我看到的速度实在是太不合理了,甚至在一次失败之前都不可能是正确的“改进。如果我选择10万分,就需要几天或几周的时间。看来一定是出了什么事。但我会尽快尝试更新。@kazemakase你说得对!看,这是在0.19完全重构的,“改进”是一个轻描淡写的说法。我明白了!因此,“改进”是一种轻描淡写的说法。很好,我被卖了,谢谢@哦,这就是我在19.1版上看到的曲线。@kazemakase很高兴听到,谢谢你的确认。我明白了!因此,“改进”是一种轻描淡写的说法。很好,我被卖了,谢谢@哦,这就是我在19.1版上看到的曲线。@kazemakase很高兴听到这个消息,谢谢你的确认。
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()
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)