【问题标题】:Python Numpy polyfit results differ from SciPy interpolatePython Numpy polyfit 结果与 SciPy interpolate 不同
【发布时间】:2018-11-05 15:50:14
【问题描述】:

我必须使用无法推断的旧 scipy 版本。 在 scipy 1.1.0 中,外推按预期工作,给出了正确的结果。 由于我不能在我的应用程序中使用它,我想使用 numpy polyfit。 但结果不同,而从 scipy 和 bisect 插值的结果是相同的..

class InterExtraPolate(object):
  def __init__(self, x_list, y_list):
    if any(y - x <= 0 for x, y in zip(x_list, x_list[1:])):
      raise ValueError("x_list must be in strictly ascending order!")
    self.x_list = map(float, x_list)
    self.y_list = map(float, y_list)
  def __getitem__(self, x):
    from scipy import interpolate
    f=interpolate.interp1d(self.x_list,self.y_list, fill_value='extrapolate')
    return f(x)


class npInterExraPolate(object):
  def __init__(self, x_list, y_list):
    import numpy as np
    if any(y - x <= 0 for x, y in zip(x_list, x_list[1:])):
      raise ValueError("x_list must be in strictly ascending order!")
    self.x_list = map(float, x_list)
    self.y_list = map(float, y_list)
    self.fit=np.polyfit(self.x_list,self.y_list, 1)

  def __getitem__(self, x):
    import numpy as np
    f=np.poly1d(self.fit)
    return f(x)

##Main


ie   =  InterExtraPolate([1, 2.5, 3.4, 5.8, 6], [2, 4, 5.8, 4.3, 4])
npie = npInterExraPolate([1, 2.5, 3.4, 5.8, 6], [2, 4, 5.8, 4.3, 4])

my_xl = [0.5,1.1,6.3]

print ie[my_xl]

print npie[my_xl]

==== 如何使 numpy polyfit/poly1d 结果等于 scipy 外推结果?

【问题讨论】:

    标签: python numpy scipy extrapolation


    【解决方案1】:

    如果您绘制实际结果,您很快就会明白为什么线性插值不是线性拟合:插值是从点到点进行的,而拟合会考虑所有点:

    这并没有解释如何正确地做到这一点,但应该解释为什么它会失败。

    我认为没有办法使用多项式拟合作为插值的替代方法,结果完全相同。

    您要么必须自己编写插值代码,要么找到安装更新版本的 SciPy 的方法。

    对于初学者,看看在安装 SciPy 时是否可以使用 --user 选项。您没有提及为什么必须使用旧版本,以及阻止您安装较新版本的原因。这可能是另一个要问的问题:如何规避在安装最新版本的 SciPy 时存在的任何限制。

    【讨论】:

    • 感谢您的解释。无法更新的原因是此版本作为“工具”包含在主要应用程序可执行文件中。从 2016 年开始。2018 年的更新版本可以使用 scipy 1.1.x。最终用户目前无法升级。
    【解决方案2】:

    我使用 bisect_left 解决了我的需求,并将外推部分添加到与外部斜坡相同的斜坡中。..

    class bsInterExtraPolate(object):
      def __init__(self, x_list, y_list):
        if any(y - x <= 0 for x, y in zip(x_list, x_list[1:])):
          raise ValueError("x_list must be in strictly ascending order!")
        x_list = self.x_list = map(float, x_list)
        y_list = self.y_list = map(float, y_list)
        intervals = zip(x_list, x_list[1:], y_list, y_list[1:])
        self.slopes = [(y2 - y1)/(x2 - x1) for x1, x2, y1, y2 in intervals]
    
      def __getitem__(self, x):
        #-- expanding for lin extrapolation using outer slopes
        from bisect import bisect_left
        if type(x)==list:
          yval=[]
          for xval in x:
            if xval < self.x_list[0]:
              i=0
            elif xval > self.x_list[-1]:
              i=len(self.x_list)-2
            else:
              i = bisect_left(self.x_list, xval) - 1
            ytmp=self.y_list[i] + self.slopes[i] * (xval - self.x_list[i])
            yval.append(ytmp)
        else:
          xval=float(x)
          if xval < self.x_list[0]:
            i=0
          elif xval > self.x_list[-1]:
            i=len(self.x_list)-2
          else:
            i = bisect_left(self.x_list, xval) - 1
          ytmp=self.y_list[i] + self.slopes[i] * (xval - self.x_list[i])
          yval=ytmp
        return yval
    

    【讨论】:

      猜你喜欢
      • 2018-09-16
      • 1970-01-01
      • 2022-11-01
      • 2020-05-22
      • 2023-01-13
      • 1970-01-01
      • 1970-01-01
      • 2017-11-08
      • 2012-01-30
      相关资源
      最近更新 更多