这是 scipy.interpolate.interp1d 中的错误吗?
Is this an error in scipy.interpolate.interp1d?
当使用零阶插值时,我发现输入数组中的最后一个 Y 值没有return编辑为 X 数组中的最后一个值:
from scipy.interpolate import interp1d
xx = [0.0, 1.0, 2.0]
xi = interp1d(xx, xx, kind='zero')
print(xi(xx))
似乎应该 return [0., 1., 2.] 但它 return 是 [0., 1., 1.]。 xx 中的最后一个值被认为在插值范围内,但未被 return 编辑为最后一个点的值。该文档没有提供 'zero' 的详细信息,但我希望它会:
a) 引发 ValueError 因为输入值被认为定义了半封闭范围 [0., 1.) 和 [1., 2.) 上的值,从而使 2.0 未定义,或
b) return 2.0 因为范围是 [0., 1.), [1., 2.) 和 [2., 2.)
interp1d 函数似乎认为正确答案是:
c) return 1.0 因为最后一个区间是特例,定义为闭区间 [1., 2.]
有没有正确的选择?如果有,是interp1d实现的吗?
零阶样条是分段常量,在节点处有不连续点,这里是插值点,所以xi(1.0-1e-13) == 0
和xi(1.0+1e-13) == 1
。
interp1d中的插值区间定义为闭合的,[0, 2]
。原则上人们会期望有一个浮点值,x=2.0
,它给出结果 2.0
然而,正如上面的评论所述,这里的样条实现来自 FITPACK,它将 k=0 样条定义为从右边的结处连续,除了最后一个间隔不同。我不知道原因 --- Fortran 代码可以追溯到 80 年代。我的猜测是它的工作方式没有特定原因,可能除了使用 B 样条表示编写这样的代码稍微方便一些之外。
我认为这种行为是 bug/quirk,但由于 x 值中存在的任何舍入误差都会使其影响为零,因此它的解决优先级一直很低。 (要考虑的一个方面是,由于没有具体说明它的作用,它是由实现定义的;破坏向后兼容可能比问题本身更糟糕。)
编辑:如另一个答案中所述,样条实际上是由splmake
构造的;这个例程不是来自 FITPACK。不看最后的间隔行为是由于拟合还是构造就不能说。
根据source the interval is between [0, 2], including 2. The return from creating the spline is the cvals splmake(xx, xx, 0)[1] --> array([0.0, 1.0])
. Following the source through we'll get to a call to evaluate the spline at a point which results in spleval(splmake(xx, xx, 0), 2) --> array(1.0)
. To answer your question, there's not really an answer it was just implemented this way, and if you think if the original array as encompassing the valid range I think it makes sense - but perhaps there should be a note about this particular evaluation, in which case you could always submit a request here。我不能发表评论,否则我会但希望它能回答你的问题。
当使用零阶插值时,我发现输入数组中的最后一个 Y 值没有return编辑为 X 数组中的最后一个值:
from scipy.interpolate import interp1d
xx = [0.0, 1.0, 2.0]
xi = interp1d(xx, xx, kind='zero')
print(xi(xx))
似乎应该 return [0., 1., 2.] 但它 return 是 [0., 1., 1.]。 xx 中的最后一个值被认为在插值范围内,但未被 return 编辑为最后一个点的值。该文档没有提供 'zero' 的详细信息,但我希望它会:
a) 引发 ValueError 因为输入值被认为定义了半封闭范围 [0., 1.) 和 [1., 2.) 上的值,从而使 2.0 未定义,或
b) return 2.0 因为范围是 [0., 1.), [1., 2.) 和 [2., 2.)
interp1d 函数似乎认为正确答案是:
c) return 1.0 因为最后一个区间是特例,定义为闭区间 [1., 2.]
有没有正确的选择?如果有,是interp1d实现的吗?
零阶样条是分段常量,在节点处有不连续点,这里是插值点,所以xi(1.0-1e-13) == 0
和xi(1.0+1e-13) == 1
。
interp1d中的插值区间定义为闭合的,[0, 2]
。原则上人们会期望有一个浮点值,x=2.0
,它给出结果 2.0
然而,正如上面的评论所述,这里的样条实现来自 FITPACK,它将 k=0 样条定义为从右边的结处连续,除了最后一个间隔不同。我不知道原因 --- Fortran 代码可以追溯到 80 年代。我的猜测是它的工作方式没有特定原因,可能除了使用 B 样条表示编写这样的代码稍微方便一些之外。
我认为这种行为是 bug/quirk,但由于 x 值中存在的任何舍入误差都会使其影响为零,因此它的解决优先级一直很低。 (要考虑的一个方面是,由于没有具体说明它的作用,它是由实现定义的;破坏向后兼容可能比问题本身更糟糕。)
编辑:如另一个答案中所述,样条实际上是由splmake
构造的;这个例程不是来自 FITPACK。不看最后的间隔行为是由于拟合还是构造就不能说。
根据source the interval is between [0, 2], including 2. The return from creating the spline is the cvals splmake(xx, xx, 0)[1] --> array([0.0, 1.0])
. Following the source through we'll get to a call to evaluate the spline at a point which results in spleval(splmake(xx, xx, 0), 2) --> array(1.0)
. To answer your question, there's not really an answer it was just implemented this way, and if you think if the original array as encompassing the valid range I think it makes sense - but perhaps there should be a note about this particular evaluation, in which case you could always submit a request here。我不能发表评论,否则我会但希望它能回答你的问题。