使用Python进行样条插值

14

我编写了以下代码进行样条插值:

import numpy as np
import scipy as sp

x1 = [1., 0.88,  0.67,  0.50,  0.35,  0.27, 0.18,  0.11,  0.08,  0.04,  0.04,  0.02]
y1 = [0., 13.99, 27.99, 41.98, 55.98, 69.97, 83.97, 97.97, 111.96, 125.96, 139.95, 153.95]

x = np.array(x1)
y = np.array(y1)

new_length = 25
new_x = np.linspace(x.min(), x.max(), new_length)
new_y = sp.interpolate.interp1d(x, y, kind='cubic')(new_x)

但是我得到的是:

ValueError: A value in x_new is below the interpolation range.

interpolate.py中。

非常感谢任何帮助。


我尝试运行你的代码,结果出现了“name 'np' is not defined”的错误。这就是你的整个程序吗? - Kevin
不,你需要导入:numpy as np,scipy as sp,scipy.interpolate。 - Hellfish
3个回答

19

scipy.interpolate.interp1d的文档中得知:

scipy.interpolate.interp1d(x, y, kind='linear', axis=-1, copy=True, bounds_error=True, fill_value=np.nan)

x:array_like。一个单调递增的实数数组。

...

问题在于x值不是单调递增的,事实上它们是单调递减的。如果这个方法可以解决你的计算问题,请告诉我。

import numpy as np
import scipy as sp
from scipy.interpolate import interp1d

x1 = sorted([1., 0.88, 0.67, 0.50, 0.35, 0.27, 0.18, 0.11, 0.08, 0.04, 0.04, 0.02])
y1 = [0., 13.99, 27.99, 41.98, 55.98, 69.97, 83.97, 97.97, 111.96, 125.96, 139.95, 153.95]

new_length = 25
new_x = np.linspace(x.min(), x.max(), new_length)
new_y = sp.interpolate.interp1d(x, y, kind='cubic')(new_x)

4
你可以使用 x1.reverse()y1.reverse() 而不是 sorted() - gotgenes
9
在这个例子中,x1和y1成对出现,只需要对x1数组进行排序。y1数组应该以与x1数组相同的方式洗牌。 - Vasco

14

您可以通过以下方式获得:

import numpy as np
import scipy as sp
from scipy.interpolate import interp1d

x1 = [1., 0.88,  0.67,  0.50,  0.35,  0.27, 0.18,  0.11,  0.08,  0.04,  0.04,  0.02]
y1 = [0., 13.99, 27.99, 41.98, 55.98, 69.97, 83.97, 97.97, 111.96, 125.96, 139.95, 153.95]

# Combine lists into list of tuples
points = zip(x1, y1)

# Sort list of tuples by x-value
points = sorted(points, key=lambda point: point[0])

# Split list of tuples into two list of x values any y values
x1, y1 = zip(*points)

new_length = 25
new_x = np.linspace(min(x1), max(x1), new_length)
new_y = sp.interpolate.interp1d(x1, y1, kind='cubic')(new_x)

3
使用上面的代码,在Python 3.6中最后一行出现了以下错误:ValueError: Expect x to be a 1-D sorted array_like. 该错误意味着期望输入的x是一个一维已排序的数组或类似数组。 - K.-Michael Aye
@K.-MichaelAye 对我来说,Python 2.7和Python 3.5都可以正常运行。我使用的是numpy 1.11和scipy 0.17.0版本。你使用的是哪个版本? - Martin Thoma
确实,在Python 3.5、numpy 1.11.3和scipy 0.17.1下它可以工作。它也可以在scipy 0.18.1和numpy 1.11.3下工作,但是在scipy 0.19.1下就会出现问题。显然,interp1d现在已经被弃用了。 - K.-Michael Aye
@K.-MichaelAye:谢谢。interp1d 似乎没有被弃用,但是的确在 scipy 0.19 上失败了,并且在 0.18.1 上运行正常。 - Adobe
1
请参见此处的讨论,interp1d现在已更名为UnivariateSpline https://github.com/scipy/scipy/issues/4304 - K.-Michael Aye

0

我刚刚遇到了上述错误,并通过从 X 和 Y 数组中去除重复值来解决它。

x = np.sort(np.array([0, .2, .2, .4, .6, .9]))
y = np.sort(np.sort(np.array([0, .1, .06, .11, .25, .55]))

0.2更改为0.3或任何数字。

x = np.sort(np.array([0, .2, .3, .4, .6, .9]))
y = np.sort(np.sort(np.array([0, .1, .06, .11, .25, .55]))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接