【发布时间】:2016-04-11 03:56:22
【问题描述】:
在使用 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: Invalid inputs
结果我给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 在案例 2 中有效,但在案例 1 中无效?
或者,换句话说:当二维插值仅沿一个方向输入时(案例 1 和 2 失败),我们是否希望它返回错误? (情况 1 和 2 应该返回一些东西,即使是不可预测的)。
【问题讨论】:
-
哪个函数或子调用返回 ValueError?我在
bisplrep中没有看到这样的raise。此函数是 FORTRAN 库 FITPACK 的前端。像这样的库并不以用户友好而著称。它们是由专家为自己和其他专家编写的。 -
我很确定这样就可以了。考虑双线性插值:沿着
x和y进行插值,基本上是独立的。这意味着输入数据必须对插值有效。但是,如果在您的输入数据中,其中一个轴是恒定的,则您无法沿该方向进行插值。在这种情况下,您只是缺少信息。 -
只是为了让我的观点更清楚:坐标轴的方向在通常的二维插值中会产生非常大的偏差。考虑双线性情况:插值函数的偏导数的不连续性由笛卡尔轴的方向决定。因此,无论您的数据是沿轴定向还是在某些不同的配置中,这非常重要。这就是为什么有一条倾斜的输入线(使用
interp2d(x,x,z))在计算上要好得多:有一堆x和y值,即使在几何上你仍然使用一条线。
标签: python scipy interpolation