问题描述
我已经能够成功地将值从 x
的线性值插入到 y
的类正弦值。
但是 - 我正在努力插入另一种方式 - 从 y
的非线性值到 x
的线性值。
下面是一个玩具示例
import matplotlib.pylab as plt
from scipy import interpolate
#create 100 x values
x = np.linspace(-np.pi,np.pi,100)
#create 100 values of y where y= sin(x)
y=np.sin(x)
#learn function to map y from x
f = interpolate.interp1d(x,y)
使用新的线性值 x
xnew = np.array([-1,1])
我得到了非线性 y
的正确内插值
ynew = f(xnew)
print(ynew)
array([-0.84114583,0.84114583])
当我尝试从 x
插入 y
的值时出现问题。
f2 = interpolate.interp1d(y,x,kind='cubic')
我输入了之前成功插入的 y 值
ynew=np.array([-0.84114583,0.84114583])
我希望得到 x
[-1,1] 的原始值
但我明白了:
array([-1.57328791,1.57328791])
我尝试为 'kind' 参数输入其他值,但没有成功,我不确定这里是否有错误的方法。感谢您的帮助
解决方法
我猜问题出自这样一个事实,即 x
不是 y
的函数,因为对于任意 y
值可能有多个 x
找到值。
查看截断的数据范围。
当 x
的范围从 0 到 np.pi/2
时,每个 y
值都有一个唯一的 x
值。
在这种情况下,下面的代码段按预期工作。
>>> import numpy as np
>>> from scipy import interpolate
>>> x = np.linspace(0,np.pi / 2,100)
>>> y = np.sin(x)
>>> f = interpolate.interp1d(x,y)
>>> f([0,0.1,0.3,0.5])
array([0.,0.09983071,0.29551713,0.47941047])
>>> f2 = interpolate.interp1d(y,x)
>>> f2([0,0.47941047])
array([0.,0.50000001])
,
Maxim 提供了这种行为的原因。此插值是一个设计用于函数的类。在您的情况下, y=arcsin(x)
仅在有限区间内是一个函数。这导致插值例程中出现有趣的现象,即插值到最近的 y 值,在 arcsin()
函数的情况下,该值不一定是 x-y 曲线中的下一个值,但可能是几个周期之外的值。一个说明:
import numpy as np
import matplotlib.pylab as plt
from scipy import interpolate
xmin=-np.pi
xmax=np.pi
fig,axes = plt.subplots(3,3,figsize=(15,10))
for i,fac in enumerate([2,1,0.5]):
x = np.linspace(xmin * fac,xmax*fac,100)
y=np.sin(x)
#x->y
f = interpolate.interp1d(x,y)
x_fit = np.linspace(xmin*fac,1000)
y_fit = f(x_fit)
axes[i][0].plot(x_fit,y_fit)
axes[i][0].set_ylabel(f"sin period {fac}")
if not i:
axes[i][0].set_title(label="interpolation x->y")
#y->x
f2 = interpolate.interp1d(y,x)
y2_fit = np.linspace(.99 * min(y),.99 * max(y),1000)
x2_fit = f2(y2_fit)
axes[i][1].plot(x2_fit,y2_fit)
if not i:
axes[i][1].set_title(label="interpolation y->x")
#y->x with cubic interpolation
f3 = interpolate.interp1d(y,x,kind="cubic")
y3_fit = np.linspace(.99 * min(y),1000)
x3_fit = f3(y3_fit)
axes[i][2].plot(x3_fit,y3_fit)
if not i:
axes[i][2].set_title(label="cubic interpolation y->x")
plt.show()
如您所见,插值是按照 y 值的有序列表进行的(按照您的指示),这对于三次插值尤其不利。