首页 文章

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

提问于
浏览
4

使用零阶插值时,我发现输入数组中的最后一个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 回答

  • 2

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

    interp1d中的插值间隔定义为closed, [0, 2] . 原则上可以预期有一个浮点值 x=2.0 ,它给出了结果2.0

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

    在我看来,这种行为是bug/quirk,但由于x值中存在任何舍入误差使其影响为零,因此它由实现定义;打破向后比较可能比问题本身更糟糕 . )

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

  • 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 . 我不能评论否则我会,但希望它回答你的问题 .

相关问题