SciPy/NumPy中一维线性插值的函数对象替代方案是什么?
我在找一种方法,想用SciPy(或者NumPy)来创建一个“函数”,用于线性插值时间和数值的配对,但根据SciPy的教程,似乎没有这样的功能!这跟理解scipy和numpy插值的情况正好相反。
最自然的方法是使用interp1d,但它有个警告:
遗留 这个类被认为是遗留的,不会再更新了。[…] 如果你想了解interp1d的替代方法,可以查看一维插值。
点击那个链接后,我看到的内容是:
如果你只需要线性(也就是折线)插值,可以使用numpy.interp这个方法。
问题是,这两者根本不一样。numpy.interp
要求我提前知道所有的点,并且它不会返回一个可以用来查找插值的函数。
与此同时,SciPy还有很多其他的插值方法,它们都返回一个函数(或者函数对象),比如CubicSpline
或者PchipInterpolator
。
那么,现在interp1d
被弃用了,有什么简单的方法可以构建一个类似于PchipInterpolator
返回的函数或对象,用于简单的线性插值呢?
2 个回答
1
如果你需要的话,可以把 numpy.interp
包装成一个函数。下面是用 numpy.interp
重现官方文档中的一个例子:
import numpy as np
from scipy import interpolate
x = np.arange(0, 10)
y = np.exp(-x/3.0)
f1 = interpolate.interp1d(x, y)
def f2(i):
return np.interp(i, x, y)
xnew = np.arange(0, 9, 0.1)
np.isclose(f1(xnew), f2(xnew)) # Returns True
你可以在函数定义里添加数据点,并为每种情况构建“函数对象”。
另外,你也可以:
from functools import partial
f2 = partial(np.interp, xp=x, fp=y)
甚至可以创建一个“函数对象”,类似于 scipy.interpolate.interp1d
:
from functools import partial
def interp1d(x, y):
return partial(np.interp, xp=x, fp=y)
f2 = interp1d(x, y)
2
你可以使用 scipy.interpolate.make_interp_spline
这个函数,并把 k
设置为 1
来进行线性插值。
import numpy as np
from scipy.interpolate import make_interp_spline, interp1d
import matplotlib.pyplot as plt
plt.close("all")
x = np.linspace(0, 20, 10)
y = np.cos(x**2)/(x+1)
x_fine = np.linspace(0, 20, 100)
y_np = np.interp(x_fine, x, y)
f_sp1 = make_interp_spline(x, y, k=1)
y_sp1 = f_sp1(x_fine)
f_sp2 = interp1d(x, y)
y_sp2 = f_sp2(x_fine)
fig, ax = plt.subplots()
ax.plot(x, y, ".", label="Original")
ax.plot(x_fine, y_np, label="Numpy")
ax.plot(x_fine, y_sp1, label="Scipy (make_interp_spline)")
ax.plot(x_fine, y_sp2, label="Scipy (interp1d)")
ax.legend()
fig.show()