这是scipy.interpolate.interp1d中的错误吗?

时间:2015-01-15 20:34:34

标签: python scipy

使用零阶插值时,我发现输入数组中的最后一个Y值不会返回X数组中的最后一个值:

from scipy.interpolate import interp1d

xx = [0.0, 1.0, 2.0]
xi = interp1d(xx, xx, kind='zero')
print(xi(xx))

似乎应该返回[0.,1.,2。]但它返回[0,1。,1。]。 xx中的最后一个值被认为是在插值范围内,但不会作为最后一个点的值返回。文档没有提供“零”的详细信息,但我希望它可以:

a)引发ValueError,因为输入值被认为是在半闭合范围[0,1。]和[1.,2。}上定义值,从而留下2.0未定义,或

b)返回2.0,因为范围是[0,1。),[1.,2。]和[2.,2。]

interp1d函数似乎认为正确的答案是:

c)返回1.0,因为最后一个范围是一个特殊情况,定义为一个封闭的区间[1.,2。]

有正确的选择吗?如果是这样,它是由interp1d实现的吗?

2 个答案:

答案 0 :(得分:2)

零阶样条曲线是分段常数,并且在节点处具有不连续性,这里是插值点,因此xi(1.0-1e-13) == 0xi(1.0+1e-13) == 1

interp1d中的插值间隔定义为闭合[0, 2]。原则上可以预期存在单个浮点值x=2.0,其给出结果2.0

然而,正如上面的注释中所指出的,这里的样条实现来自FITPACK,它将k = 0样条定义为从右边开始的连续,除了最后一个不同的间隔。我不知道原因--- Fortran代码可以追溯到80年代。我的猜测是它的工作方式没有特定的原因,可能除了使用B样条表示法编写这样的代码稍微方便之外。

在我看来,这种行为是bug/quirk,但由于x值中存在任何舍入误差会使其影响为零,因此优先解决这个问题。 (需要考虑的一个方面是,由于没有说明它的作用,它是由实现定义的;打破后向compat可能比问题本身更糟糕。)

编辑:如另一个答案中所述,样条实际上是由splmake构建的;这个例程不是来自FITPACK。不看是否最终的间隔行为是由于拟合还是构造。

答案 1 :(得分:1)

根据source,间隔在[0,2]之间,包括2.创建样条曲线的返回值为cvals splmake(xx, xx, 0)[1] --> array([0.0, 1.0])。通过我们的来源,我们会打电话来评估一个导致spleval(splmake(xx, xx, 0), 2) --> array(1.0)的点的样条曲线。要回答你的问题,这个方法实际上并没有真正的答案,如果你认为原始数组是否包含有效范围,我认为它是有意义的 - 但也许应该有一个关于这一点的说明评估,在这种情况下,您始终可以提交请求here。我不能发表评论,但我希望它会回答你的问题。