python - 使用 scipy 进行二维插值/平滑线时如何提高性能?

标签 python python-2.7 numpy scipy scientific-computing

我有一个中等大小的数据集,即两列矩阵中的 20000 x 2 float 。第一列是 x 列,表示沿轨迹到原点的距离,另一列是 y 列,表示对对象所做的功。该数据集是从实验室操作中获得的,因此它相当任意。我已经把这个结构变成了 numpy 数组。我想在具有平滑曲线的图中绘制 y 与 x 的关系。所以我希望下面的代码可以帮助我:

x_smooth = np.linspace(x.min(),x.max(), 20000)
y_smooth = spline(x, y, x_smooth)
plt.plot(x_smooth, y_smooth)
plt.show()

但是,当我的程序执行y_smooth = spline(x,y,x_smooth)这行代码时,需要很长时间,比如10分钟,甚至有时它会破坏我的内存必须重新启动我的机器。我尝试将 block 数减少到 200 和 2000,但都不起作用。然后我查了官方的scipy引用:scipy.interpolate.spline 这里。他们说 spline 在 v 0.19 中已被弃用,但我没有使用新版本。如果 spline 在相当长一段时间内已被弃用,那么现在如何使用等效的 Bspline 呢?如果spline仍然起作用,那么是什么导致性能缓慢

我的数据的一部分可能如下所示:

13.202      0.0
13.234738      -0.051354643759
12.999116      0.144464320836
12.86252      0.07396528119
13.1157      0.10019738758
13.357109      -0.30288563381
13.234004      -0.045792536285
12.836279      0.0362257166275
12.851597      0.0542649286915
13.110691      0.105297378401
13.220619      -0.0182963209185
13.092143      0.116647353635
12.545676      -0.641112204849
12.728248      -0.147460703493
12.874176      0.0755861585235
12.746764      -0.111583725833
13.024995      0.148079528382
13.106033      0.119481137144
13.327233      -0.197666132456
13.142423      0.0901867159545

最佳答案

这里有几个问题。首先也是最重要的,您尝试使用的样条拟合是全局的。这意味着您在构建时求解大小为 20000 的线性方程组(尽管评估对数据集大小很弱敏感)。这解释了为什么样条线构建速度很慢。

此外,

scipy.interpolate.spline 使用完整矩阵进行线性代数——因此会消耗内存。这正是它从 scipy 0.19.0 开始被弃用的原因。

推荐的替代方案(在 scipy 0.19.0 中提供)是 BSpline/make_interp_spline 组合:

>>> spl = make_interp_spline(x, y, k=3)    # returns a BSpline object
>>> y_new = spl(x_new)                     # evaluate 

请注意,它不是 BSpline(x, y, k):BSpline 对象不知道有关数据、拟合或插值的任何信息。

如果您使用的是较旧的 scipy 版本,您的选择是:

  • CubicSpline(x, y) 用于三次样条
  • splrep(x, y, s=0)/splev 组合。

但是,您可能需要考虑是否真的需要两次连续可微的函数。如果只有一次可微函数对于您的目的来说足够平滑,那么您可以使用局部样条插值,例如Akima1DInterpolatorPchipInterpolator:

In [1]: import numpy as np

In [2]: from scipy.interpolate import pchip, splmake

In [3]: x = np.arange(1000)

In [4]: y = x**2

In [5]: %timeit pchip(x, y)
10 loops, best of 3: 58.9 ms per loop

In [6]: %timeit splmake(x, y)    
1 loop, best of 3: 5.01 s per loop

这里 splmakespline 在底层使用的,它也已被弃用。

关于python - 使用 scipy 进行二维插值/平滑线时如何提高性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43644790/

相关文章:

python - 多项选择计划和迭代 (2.7)

python - 如何在numpy中组合数组?

python - 将 C 字符串公开给 NumPy 的最快方法?

python - 映射键列表以从字典中删除键

Python IDLE 卡住

c# - windows下自动SSH登录

python - 使用 keras 和 python 3.6 构建神经网络

python - Kafka-python 获取主题的分区数

Python 天真的eBayes : Why am I getting a ZeroDivisionError

python - 有没有更有效的方法来切片多维数组