【问题标题】:SciPy interp2D for pairs of coordinates坐标对的 SciPy interp2D
【发布时间】:2019-06-13 07:42:28
【问题描述】:

我正在使用scipy.interpolate.interp2d 为表面创建插值函数。然后,我有两个要计算插值点的真实数据数组。如果我将这两个数组传递给 interp2d 函数,我会得到一个包含所有点的数组,而不仅仅是点对。

我对此的解决方案是将两个数组压缩到坐标对列表中,然后循环传递给插值函数:

f_interp = interpolate.interp2d(X_table, Y_table,Z_table, kind='cubic')

co_ords = zip(X,Y)
out = []
for i in range(len(co_ords)):
    X = co_ords[i][0]
    Y = co_ords[i][1]
    value = f_interp(X,Y)
    out.append(float(value))

我的问题是,有没有更好(更优雅,Pythonic?)的方法来实现相同的结果?

【问题讨论】:

    标签: python scipy interpolation


    【解决方案1】:

    一次传递所有点可能比在 Python 中循环遍历它们要快得多。你可以使用scipy.interpolate.griddata:

    Z = interpolate.griddata((X_table, Y_table), Z_table, (X, Y), method='cubic')
    

    scipy.interpolate.BivariateSpline 类之一,例如SmoothBivariateSpline:

    itp = interpolate.SmoothBivariateSpline(X_table, Y_table, Z_table)
    # NB: choose grid=False to get an (n,) rather than an (n, n) output
    Z = itp(X, Y, grid=False)
    

    CloughTocher2DInterpolator 也以类似的方式工作,但没有grid=False 参数(它总是返回一维输出)。

    【讨论】:

      【解决方案2】:

      尝试 *args 和元组打包/解包

      points = zip(X, Y)
      out = []
      for p in points:
          value = f_interp(*p)
          out.append(float(value))
      

      或者只是

      points = zip(X, Y)
      out = [float(f_interp(*p)) for p in points]
      

      或者只是

      out = [float(f_interp(*p)) for p in zip(X, Y)]
      

      作为旁注,“魔法之星”允许 zip 是它自己的逆!

      points = zip(x, y)
      x, y   = zip(*points)
      

      【讨论】:

        【解决方案3】:

        一方面,你可以做到

        for Xtmp,Ytmp in zip(X,Y):
            ...
        

        在你的循环中。甚至更好,只是

        out = [float(f_interp(XX,YY)) for XX,YY in zip(X,Y)]
        

        替换循环。

        换一种说法,I suggest using interpolate.griddata。它的表现往往比interp2d 好得多,并且它接受任意形状的点作为输入。如您所见,interp2d 插值器只会返回网格上的值。

        【讨论】:

          【解决方案4】:

          thread 的启发,有人建议使用 interp2d 函数的内部权重,我创建了以下包装器,它与interp2d 具有完全相同的接口,但插值器评估输入对并返回一个 numpy 数组其输入的形状相同。性能应该优于 for 循环或列表理解,但在网格上评估时,scipy interp2d 的性能会略胜一筹。

          import scipy.interpolate as si
          def interp2d_pairs(*args,**kwargs):
              """ Same interface as interp2d but the returned interpolant will evaluate its inputs as pairs of values.
              """
              # Internal function, that evaluates pairs of values, output has the same shape as input
              def interpolant(x,y,f):
                  x,y = np.asarray(x), np.asarray(y)
                  return (si.dfitpack.bispeu(f.tck[0], f.tck[1], f.tck[2], f.tck[3], f.tck[4], x.ravel(), y.ravel())[0]).reshape(x.shape)
              # Wrapping the scipy interp2 function to call out interpolant instead
              return lambda x,y: interpolant(x,y,si.interp2d(*args,**kwargs))
          
          # Create the interpolant (same interface as interp2d)
          f = interp2d_pairs(X,Y,Z,kind='cubic')
          # Evaluate the interpolant on each pairs of x and y values
          z=f(x,y)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-06-27
            • 2016-09-21
            • 1970-01-01
            • 2016-04-11
            • 1970-01-01
            • 2012-01-29
            • 1970-01-01
            相关资源
            最近更新 更多