为什么SciPy的interp1d会花一分钟以上的时间来构建插值器? [英] Why would SciPy's interp1d take over a minute to build an interpolator?

查看:154
本文介绍了为什么SciPy的interp1d会花一分钟以上的时间来构建插值器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想对1d中的一连串浮点数(或向量)进行四边形或立方插值,其中long可能是1E + 05或1E + 06(或更多).由于某种原因,SciPi方便的interp1d()用来准备插值器的时间开销对于二次和三次样条曲线几乎都缩放为n ^ 3,花费一分钟的时间达到几千点.

I'd like to quad or cube interpolate a long series of floats (or vectors) in 1d, where long could be 1E+05 or 1E+06 (or more). For some reason SciPi's handy interp1d()'s time overhead to prepare the interpolators scales as almost n^3 for both quadratic and cubic splines, taking over a minute for a few thousand points.

根据评论此处(我将删除的问题,我暂时将其保留在此处以进行评论访问)在其他计算机上花费的时间为毫秒,因此此处在病理上显然是错误的.

According to comments here (a question I will delete, I'm keeping it there temporarily for comment access) it takes a milli-second on other computers, so something is obviously pathologically wrong here.

我的装置有些旧,但是SciPy的.interp1d()已经存在了一段时间.

My installation is a bit old, but SciPy's .interp1d() has been around for quite a while.

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

我该怎么做才能找出这种难以置信的内插速度?

What can I do to try to figure out this incredible slowness for interpolation?

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

推荐答案

简短的答案:更新您的scipy安装.

Short answer: update your scipy installation.

更长的答案:0.19之前的版本,interp1d基于splmake,后者使用具有完整矩阵的线性代数.在scipy 0.19中,将其重构为使用带状线性代数.结果,(下面是scipy 0.19.1)

Longer answer: pre-0.19, interp1d was based on splmake which is using linear algebra with full matrices. In scipy 0.19, it was refactored to use banded linear algebra. As a result, (below is with 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)

如果您要专门使用三次样条曲线(这是scipy 0.18中的新功能),您还可以选择CubicSpline;如果您也想得到二次样条曲线(scipy 0.19的新功能),则是make_interp_spline;这是interp1d在罩).

Your other options are CubicSpline if you want cubic splines specifically (this is new in scipy 0.18) or make_interp_spline if you want also quadratic splines (new in scipy 0.19; this is what interp1d is using under the hood).

这篇关于为什么SciPy的interp1d会花一分钟以上的时间来构建插值器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆