Python 给定1D输入时scipy interp2d/bisplrep意外输出
我在使用scipyPython 给定1D输入时scipy interp2d/bisplrep意外输出,python,scipy,interpolation,Python,Scipy,Interpolation,我在使用scipyinterp2d函数时遇到了无效的输入错误。原来问题来自bisplrep函数,如下所示: import numpy as np from scipy import interpolate # Case 1 x = np.linspace(0,1) y = np.zeros_like(x) z = np.ones_like(x) tck = interpolate.bisplrep(x,y,z) # or interp2d 返回:ValueError:无效输入 结果证明,
interp2d
函数时遇到了无效的输入错误。原来问题来自bisplrep
函数,如下所示:
import numpy as np
from scipy import interpolate
# Case 1
x = np.linspace(0,1)
y = np.zeros_like(x)
z = np.ones_like(x)
tck = interpolate.bisplrep(x,y,z) # or interp2d
返回:ValueError:无效输入
结果证明,我给出的测试数据interp2d
只包含第二个轴的一个不同值,如上面的测试样本所示。interp2d
内部的bisplrep
函数将其视为无效输出:
这可能被认为是一种可接受的行为:interp2d
&bisplrep
需要一个二维网格,我只沿着一条线给它们赋值
另一方面,我发现错误信息非常不清楚。可以在interp2d
中包含一个测试来处理这种情况:类似于
可能足以检测此类无效输入,并发出更明确的错误消息,甚至可以直接调用更合适的interp1d
函数(在这里工作得很好)
我认为我正确地理解了这个问题。但是,请考虑下面的代码示例:
# Case 2
x = np.linspace(0,1)
y = x
z = np.ones_like(x)
tck = interpolate.bisplrep(x,y,z)
在这种情况下,y
与x
成比例,我也在沿着一条线向bisplrep
输入数据。但是,令人惊讶的是,bisplrep
在这种情况下能够计算二维样条插值。我画了它:
# Plot
def plot_0to1(tck):
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
X = np.linspace(0,1,10)
Y = np.linspace(0,1,10)
Z = interpolate.bisplev(X,Y,tck)
X,Y = np.meshgrid(X,Y)
fig = plt.figure()
ax = Axes3D(fig)
ax.plot_surface(X, Y, Z,rstride=1, cstride=1, cmap=cm.coolwarm,
linewidth=0, antialiased=False)
plt.show()
plot_0to1(tck)
结果如下:
其中,bisplrep
似乎用0来填补空白,当我扩展下面的图时更好地显示了这一点:
关于是否需要添加0,我真正的问题是:为什么bisplrep
在案例2中有效,而在案例1中无效?
或者,换句话说:当2D插值仅沿一个方向输入时(情况1和2失败),我们是否希望它返回错误?(案例1和案例2应该会返回一些东西,即使是不可预测的)。我原本打算向您展示,如果输入数据沿坐标轴而不是一般方向定向,那么2d插值会有多大的不同,但结果会比我预期的更混乱。我尝试在插值矩形网格上使用随机数据集,并将其与相同的
x
和y
坐标旋转45度进行插值的情况进行比较。结果糟透了
然后,我尝试与更平滑的数据集进行比较:结果发现scipy.interpolate.interp2d
有很多问题。所以我的底线是“使用scipy.interpolate.griddata
”
出于指导目的,以下是我的(相当混乱的)代码:
这是一个结果画廊。使用随机输入z
数据和interp2d
,笛卡尔(左)与旋转插值(右):
注意右侧可怕的刻度,注意输入点在0
和1
之间。即使是它的母亲也无法识别数据集。请注意,在对旋转数据集求值的过程中会出现运行时警告,因此我们被警告说这都是废话
现在,让我们对griddata
执行同样的操作:
我们应该注意到,这些数字彼此非常接近,它们似乎比interp2d
的输出更有意义。例如,注意第一个数字的比例中的超调
这些工件总是出现在输入数据点之间。由于它仍然是插值,输入点必须由插值函数重新生成,但是线性插值函数在数据点之间的超调非常奇怪。很明显,griddata
没有受到这个问题的影响
考虑一个更清楚的情况:另一组平滑且确定的z
值。具有interp2d
的曲面:
| Notes
| -----
| The minimum number of data points required along the interpolation
| axis is ``(k+1)**2``, with k=1 for linear, k=3 for cubic and k=5 for
| quintic interpolation.
救命啊!叫警察!笛卡尔输入法已经有了令人费解的(至少在我看来)虚假特征,旋转输入案例和旋转输入案例构成的旋转输入案例构成的威胁和旋转输入案例构成的旋转输入案例构成的威胁和旋转输入案例构成的威胁,以及旋转输入案例构成的旋转输入案例构成的威胁和旋转输入案例构成的威胁和旋转输入案例构成的威胁,以及旋转输入案例构成的威胁和旋转输入案例构成的威胁,以及旋转输入案例构成的威胁和旋转输入案例构成的威胁,以及旋转输入案例构成的威胁和旋转输入案例构成的威胁和旋转输入案例构成的威胁,以及旋转输入案例构成的威胁和旋转输入案例构成的威胁,以及旋转输入案例构成的威胁和旋转输入案例构成的威胁,以及旋转输入案例构成的威胁,以及旋转输入案例构成构成的威胁和旋转输入案例构成的威胁,以及旋转输入案例构成构成的威胁和旋转输入案例构成构成的威胁,以及旋转输入案例构成的威胁,以及旋转输入案例构成构成的威胁,以及旋转输入案例构成构成的威胁,以及旋转输入案例构成构成构成的威胁,以及旋转输入案例构成的威胁,以及旋转输入案例构成构成的威胁和旋转输入案例8月7日,本月7 7日,本月7日,本月7日,本月7日,本月7日,本月7日,本月7日,本月8日,本月8日,本月7日,本月7日,本月8日,本月7日,本月7日,本月7日,本月7日,本月7日,本月8日,本月5日,本月5日,本本月5日,本月月8日,本月8日,本本月8日,本本月8日,本本月8月8月8日,本本本本本本本月月月8 8 8日,本本本本本本本本月月月月8 8 8 8日,本本本本本本本本本本本本月月,本本本本本月月,本本本本月,本本本本月,本本月月,本本本本本本本本月月月8 8 8 8 8 8 8 8 8 8 8 8第八章:第七节:第七节
因此,让我们对griddata
执行同样的操作:
多亏了Powerpuff Girlsscipy.interpolate.griddata
,一天的时间得以节省。作业:用cubic
插值检查相同
顺便说一下,原始问题的简短答案在
帮助(interp.interp2d)
中:
对于线性插值,沿插值轴至少需要4个点,即必须至少存在4个唯一的x
和y
值才能获得有意义的结果。检查以下各项:
nvals = 3 # -> RuntimeWarning
x = np.linspace(0,1,10)
y = np.random.randint(low=0,high=nvals,size=x.shape)
z = x
interp.interp2d(x,y,z)
nvals = 4 # -> no problem here
x = np.linspace(0,1,10)
y = np.random.randint(low=0,high=nvals,size=x.shape)
z = x
interp.interp2d(x,y,z)
当然,这一切都与你的问题有关,比如:如果你的几何1d数据集沿着笛卡尔坐标轴,或者如果它是以一种一般的方式,坐标值假设不同的值,这会产生巨大的差异。尝试从几何1d数据集中进行2d插值可能毫无意义(或至少定义非常不明确),但如果数据沿着
x,y
平面的大致方向,则至少算法不应该中断。哪个函数或子调用返回ValueError?在bisplrep
中,我没有看到这样的raise
。此函数是FORTRAN库FITPACK的前端。这样的库并不以用户友好而闻名。它们是由专家为自己和其他专家编写的。我很确定这是可以的。考虑双线性插值:在基本上独立地沿着<代码> x < /代码>和<<代码> y>代码>内插。这意味着
| Notes
| -----
| The minimum number of data points required along the interpolation
| axis is ``(k+1)**2``, with k=1 for linear, k=3 for cubic and k=5 for
| quintic interpolation.
nvals = 3 # -> RuntimeWarning
x = np.linspace(0,1,10)
y = np.random.randint(low=0,high=nvals,size=x.shape)
z = x
interp.interp2d(x,y,z)
nvals = 4 # -> no problem here
x = np.linspace(0,1,10)
y = np.random.randint(low=0,high=nvals,size=x.shape)
z = x
interp.interp2d(x,y,z)