`ValueError:x_new中的一个值高于插值范围。除了不升序值之外,还有什么其他原因?

2024-05-17 02:36:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我在scipy interp1d函数中收到这个错误。通常,如果x不是单调递增的,就会产生这个误差。

import scipy.interpolate as spi
def refine(coarsex,coarsey,step):
    finex = np.arange(min(coarsex),max(coarsex)+step,step)
    intfunc = spi.interp1d(coarsex, coarsey,axis=0)
    finey = intfunc(finex)
    return finex, finey

for num, tfile in enumerate(files):
    tfile = tfile.dropna(how='any')
    x = np.array(tfile['col1'])
    y = np.array(tfile['col2'])
    finex, finey = refine(x,y,0.01)

代码是正确的,因为它成功地处理了6个数据文件,并在第7个文件中抛出了错误。所以数据肯定有问题。但据我所知,数据一直在增长。 很抱歉没有提供示例,因为我无法在示例上重现错误。

有两件事可以帮助我:

  1. 一些头脑风暴-如果数据确实是单调的 越来越多,还有什么可能导致这个错误?另一个暗示, 关于小数,可能在this question,但我认为 我的解(x的最小值和最大值)足够健壮,可以避免它。或者 不是吗?
  2. 有可能吗(怎么可能?)返回x_new和 它是抛出ValueError: A value in x_new is above the interpolation range.时的索引,这样我就可以看到 文件有问题吗?

更新

所以问题是,由于某种原因,max(finex)大于max(coarsex)(一个是.x39,另一个是.x4)。我希望将原始值四舍五入到2个有效数字可以解决问题,但它没有,它显示的数字更少,但仍与未显示的数字一起计算。我能怎么办?


Tags: 数据spistep错误npscipymax单调
2条回答

对你的finex计算的快速测试表明它可以(总是?)进入外推区域。

In [124]: coarsex=np.random.rand(100)
In [125]: max(coarsex)
Out[125]: 0.97393109991816473
In [126]: step=.01;finex=np.arange(min(coarsex), max(coarsex)+step, step);(max(
     ...: finex),max(coarsex))
Out[126]: (0.98273730602114795, 0.97393109991816473)
In [127]: step=.001;finex=np.arange(min(coarsex), max(coarsex)+step, step);(max
     ...: (finex),max(coarsex))
Out[127]: (0.97473730602114794, 0.97393109991816473)

同样,这是一个快速测试,可能会遗漏一些关键步骤或值。

如果您运行的是Scipy v.0.17.0或更高版本,那么您可以pass ^{} to ^{},它将进行外推,以计算出位于插值范围之外的这些值。定义插值函数如下:

intfunc = spi.interp1d(coarsex, coarsey,axis=0, fill_value="extrapolate")

不过,要提前警告!

根据数据的外观和正在执行的插值类型,外推值可能是错误的。如果有噪音或非单调数据,这一点尤其正确。在您的情况下,您可能没事,因为您的x_新值仅略大于您的插值范围。

这里简单演示了这个特性如何能够很好地工作,但也给出了错误的结果。

import scipy.interpolate as spi
import numpy as np

x = np.linspace(0,1,100)
y = x + np.random.randint(-1,1,100)/100
x_new = np.linspace(0,1.1,100)
intfunc = spi.interp1d(x,y,fill_value="extrapolate")
y_interp = intfunc(x_new)

import matplotlib.pyplot as plt
plt.plot(x_new,y_interp,'r', label='interp/extrap')
plt.plot(x,y, 'b--', label='data')
plt.legend()
plt.show()

enter image description here

因此,插值部分(红色)工作良好,但由于噪声的存在,外推部分显然无法遵循数据中的线性趋势。所以对你的数据有一些了解,并谨慎行事。

相关问题 更多 >