我试图使用scipy的插值函数反转插值函数。假设我创建了一个插值函数,
import scipy.interpolate as interpolate
interpolatedfunction = interpolated.interp1d(xvariable,data,kind='cubic')
当我指定:
时,是否有一些函数可以找到xinterpolatedfunction(x) == a
换句话说,“我希望我的插值函数等于a; xvariable的值是多少,使得我的函数等于a?”
我很欣赏我可以通过一些数值方案来做到这一点,但有更直接的方法吗?如果插值函数在xvariable中是多值的,那该怎么办?
答案 0 :(得分:7)
有专门的方法可以找到三次样条的根。最简单的用法是InterpolatedUnivariateSpline对象的.roots()
方法:
spl = InterpolatedUnivariateSpline(x, y)
roots = spl.roots()
这可以找到所有的根而不只是一个,因为通用解算器(fsolve
,brentq
,newton
,bisect
等等。
x = np.arange(20)
y = np.cos(np.arange(20))
spl = InterpolatedUnivariateSpline(x, y)
print(spl.roots())
输出array([ 1.56669456, 4.71145244, 7.85321627, 10.99554642, 14.13792756, 17.28271674])
但是,您希望将样条曲线等同于某个任意数字a而不是0.一个选项是重建样条曲线(您不能只从中减去a
):
solutions = InterpolatedUnivariateSpline(x, y - a).roots()
请注意,这些都不适用于interp1d
返回的函数;它没有roots
方法。对于该函数,使用诸如fsolve
之类的通用方法是一种选择,但您一次只能获得一个根。在任何情况下,当有更强大的方法进行相同类型的插值时,为什么要使用interp1d
作为三次样条线?
可以直接从样条系数中减去a
,而不是在从数据中减去a
后重建样条曲线。这要求我们采用非面向对象的插值方法。具体来说,sproot
接受由splrep
准备的tck元组,如下所示:
tck = splrep(x, y, k=3, s=0)
tck_mod = (tck[0], tck[1] - a, tck[2])
solutions = sproot(tck_mod)
我不确定弄乱tck
是否值得在这里获得收益,因为无论如何,大部分计算时间都可能在根查找中。但是有其他选择是好的。
答案 1 :(得分:4)
创建插值函数interp_fn
后,您可以通过函数的根找到x
interp_fn(x) == a
的值
interp_fn2 = lambda x: interp_fn(x) - a
有许多选项可以在scipy.optimize
中找到根。例如,使用牛顿方法,初始值从10开始:
from scipy import optimize
optimize.newton(interp_fn2, 10)
创建插值函数,然后找到fn(x) == 5
import numpy as np
from scipy import interpolate, optimize
x = np.arange(10)
y = 1 + 6*np.arange(10) - np.arange(10)**2
y2 = 5*np.ones_like(x)
plt.scatter(x,y)
plt.plot(x,y)
plt.plot(x,y2,'k-')
plt.show()
# create the interpolated function, and then the offset
# function used to find the roots
interp_fn = interpolate.interp1d(x, y, 'quadratic')
interp_fn2 = lambda x: interp_fn(x)-5
# to find the roots, we need to supply a starting value
# because there are more than 1 root in our range, we need
# to supply multiple starting values. They should be
# fairly close to the actual root
root1, root2 = optimize.newton(interp_fn2, 1), optimize.newton(interp_fn2, 5)
root1, root2
# returns:
(0.76393202250021064, 5.2360679774997898)
答案 2 :(得分:0)
如果数据是单调的,您也可以尝试:
反函数= interpolated.interp1d(data,xvariable,kind ='cubic')