简体   繁体   English

在python中进行样条插值的更快方法

[英]faster way to do spline interpolation in python

I am trying to interpolate 30 points with a degree 3 spline like so:我试图用 3 次样条插值 30 个点,如下所示:

from sympy import interpolating_spline
domain_points = [0.01, 0.01888888888888889, 0.027777777777777776, 0.03666666666666667, 0.04555555555555556, 0.05444444444444445, 0.06333333333333332, 0.07222222222222222, 0.0811111111111111, 0.09, 0.09888888888888889, 0.10777777777777778, 0.11666666666666665, 0.12555555555555556, 0.13444444444444445, 0.14333333333333334, 0.15222222222222223, 0.16111111111111112, 0.17, 0.30833333333333335, 0.44666666666666666, 0.5850000000000001, 0.7233333333333334, 0.8616666666666667, 1.0, 2.5, 4.0, 5.5, 7.0, 8.5]
range_points = list(map(lambda x: x-1/x, domain_points))

interpolating_spline(3, x, domain_points, range_points)

This takes approximately ~1min 42s on my machine.这在我的机器上大约需要大约 1 分 42 秒。 Am I doing something wrong making this so slow?我做错了什么让这变得如此缓慢吗? Is there a way to speed this up or an alternative library for spline interpolation that is faster so I could interpolate a lot more points?有没有办法加快这个速度,或者有一个更快的样条插值替代库,这样我就可以插值更多的点?

If you just want numeric interpolation use scipy如果您只想要数字插值,请使用 scipy

https://docs.scipy.org/doc/scipy/reference/tutorial/interpolate.html#spline-interpolation https://docs.scipy.org/doc/scipy/reference/tutorial/interpolate.html#spline-interpolation

Sympy is for algebraic manipulation. Sympy 用于代数运算。

Use scipy.interpolate.splrep() .使用scipy.interpolate.splrep() Its default is k=3 but its supports upto k=5 .它的默认值是k=3但它最多支持k=5

EDIT in response to the comment below you could also use interpolate.InterpolatedUnivariateSpline() which actually gives you the same result.编辑以回应下面的评论,您也可以使用interpolate.InterpolatedUnivariateSpline() ,它实际上给您相同的结果。 Code & graph updated to show this..代码和图表已更新以显示这一点..

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

domain_points = [0.01, 0.01888888888888889, 0.027777777777777776, 0.03666666666666667, 0.04555555555555556, 0.05444444444444445, 0.06333333333333332, 0.07222222222222222, 0.0811111111111111, 0.09, 0.09888888888888889, 0.10777777777777778, 0.11666666666666665, 0.12555555555555556, 0.13444444444444445, 0.14333333333333334, 0.15222222222222223, 0.16111111111111112, 0.17, 0.30833333333333335, 0.44666666666666666, 0.5850000000000001, 0.7233333333333334, 0.8616666666666667, 1.0, 2.5, 4.0, 5.5, 7.0, 8.5]
range_points  = list(map(lambda x: x-1/x, domain_points))

# using splrep
tck           = interpolate.splrep(domain_points, range_points, s=0)
splrep_points = interpolate.splev(domain_points, tck)

tock = interpolate.InterpolatedUnivariateSpline(domain_points, range_points)
xs   = np.linspace(np.min(domain_points), np.max(domain_points), 1000)

plt.figure()
plt.plot(domain_points, range_points, 'x', domain_points, splrep_points, 'b', xs, tock(xs), 'r')
plt.legend(['Data', 'splrep', 'InterpolatedUnivariateSpline'])
plt.show()

Which gives...这使...

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM