我在使用scipy的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
需要一个2D网格,而我只提供它们沿着一条线的值。
顺便说一句,我发现错误消息非常不清楚。 可以在interp2d
中包含一个测试来处理这种情况:类似以下内容的东西
if len(np.unique(x))==1 or len(np.unique(y))==1:
ValueError ("Can't build 2D splines if x or y values are all the same")
可能足以检测到这种无效的输入,并引发更明确的错误消息,甚至直接调用更合适的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
能够计算出2D样条插值。我绘制了它:
# 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
在Case 1中无法工作,但在Case 2中可以工作?
换句话说:当仅沿一个方向输入2D插值时(Case 1和2失败),我们希望它返回错误吗?还是不希望?(Case 1和2应该返回一些东西,即使是不可预测的)。
raise
。这个函数是 FITPACK 的前端,一个 FORTRAN 库。像这样的库并非以用户友好著称。它们是由专业人员为自己和其他专业人员编写的。 - hpauljinterp2d(x,x,z)
)在计算上要好得多的原因:即使几何上仍然使用一条直线,但有许多x
和y
值。 - Andras Deak -- Слава Україні