interp2d 在使用时未正确处理无序输入

interp2d not handling proprely unordered inputs when used

今天Python咬了我,interp2d我没想到的行为。我习惯了interp1d,比如定义

f = interp1d(np.linspace(0, 1, 10), np.linspace(1, 2, 10), kind='linear')

我们得到了一个插值器,它对调用参数的顺序很敏感。 f([0, 0.5, 1]) returns array([1, 1.5, 2])f([0.5, 1, 0]) returns array([1.5, 2], 1)。正如我所料。

但是,interp2d 我得到了一些不同的东西。定义后

g = interp2d([0,1], [0,1], [[1,2], [2,3]], kind='linear')

调用 g([0, 0.2, 1], [0.3]) returns array([1.3, 1.5, 2.3]),但重新排序参数没有效果。例如,g([0.2, 1, 0]) 给我完全一样。这是不希望的。我在 interp2d 的文档中找不到这方面的痕迹,更不用说更改此行为的选项了。

我也尝试将此示例转换为 RectBivariateSpline,当给定的向量未排序时调用会引发异常:ValueError("Error code returnod by bispev: 10").

我可以使用 argsort 围绕 interp2d 实现一个包装器,以便它处理顺序并在之后更正它。但我很难相信这是要走的路,假设有可能得到我想要的东西。求建议!?

interp2d的call function中有一个选项assume_sorted=False。对应的代码为:

if not assume_sorted:
    x = np.sort(x)
    y = np.sort(y)

所以默认情况下 x 和 y 并在使用前排序。但是,与 interp1d、"x and y have to be arrays of monotonically increasing values." 不同,因此设置 assume_sorted=True 会导致 ValueError: Invalid input data。别无选择,只能使用有序的 x 和 y 执行插值。

RectBivariateSpline提供选择"Whether to evaluate the results on a grid spanned by the input arrays, or at points specified by the input arrays."

例如:

from scipy.interpolate import RectBivariateSpline

g = RectBivariateSpline([0, 1, 2], [0, 1],
                        np.array([[0, 1, 2], [0, 1, 2]]).T,
                        kx=1, ky=1)  # x, and y are reversed compared to interp2d

x = [0.3, 0.2, 0.1]
y = [0.2, ]
print(g(x, y)) # -> ValueError: Error code returned by bispev: 10

x = [0.3, 0.2, 0.1]
y = [0.2,]*len(x)
print(g(x, y, grid=False)) # -> [0.3 0.2 0.1]

此处输出不再是二维网格(二维数组)上的值,而是值列表(一维数组)。