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

wil*_*ilk 5 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))
Run Code Online (Sandbox Code Playgroud)

似乎它应该返回[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执行什么?

pv.*_*pv. 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/怪癖,但由于 x 值中任何舍入误差的存在都会使其影响为零,因此解决该问题的优先级已经大大降低。(需要考虑的一个方面是,由于没有具体说明它的作用,因此它是由实现定义的;破坏向后兼容性可能比问题本身更糟糕。)

编辑:正如另一个答案中所述,样条线实际上是由splmake;构建的 该例程不是来自 FITPACK。如果不看最终的间隔行为是由于安装还是施工,就无法判断。