使用interp2d时,它们不会处理正确无序的输入

时间:2019-09-23 05:48:49

标签: python scipy interpolation

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

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

我们得到了一个插值器,它对调用它的参数的顺序很敏感。 f([0, 0.5, 1])返回array([1, 1.5, 2]),而f([0.5, 1, 0])返回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])返回array([1.3, 1.5, 2.3]),但是对参数重新排序无效。例如,g([0.2, 1, 0])给了我完全相同的东西。这是不希望的。在interp2d的文档中找不到任何痕迹,更不用说更改此行为的选项了。

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

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

1 个答案:

答案 0 :(得分:1)

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

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

因此,默认情况下,x和y会在使用前进行排序。但是,与interp1d不同,“ x和y必须是单调递增的值的数组。”因此设置assume_sorted=True会导致ValueError: Invalid input data。只能使用有序的x和y进行插值。

RectBivariateSpline提供了选择“是在由输入数组跨越的网格上,还是在由输入数组指定的点上评估结果”。

例如:

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]

在这里,输出不再是2D网格(2d数组)上的值,而是一个值列表(1d数组)。