【问题标题】:2 dimensional interpolation problem二维插值问题
【发布时间】:2010-12-30 22:51:30
【问题描述】:

我在 x 和 y 轴上有 DATA,输出在 z 上

例如

y = 10
x = [1,2,3,4,5,6]
z = [2.3,3.4,5.6,7.8,9.6,11.2]

y = 20 
x = [1,2,3,4,5,6]
z = [4.3,5.4,7.6,9.8,11.6,13.2]

y = 30 
x = [1,2,3,4,5,6]
z = [6.3,7.4,8.6,10.8,13.6,15.2]

当 y = 15 x = 3.5 时如何找到 z 的值

我曾尝试使用 scipy,但我对它很陌生

非常感谢您的帮助

振铃

【问题讨论】:

    标签: python scipy


    【解决方案1】:

    我会说只是取它周围的值的平均值。因此,如果您需要 X=3.5 和 Y=15 (3.5,15),则平均 (3,10)、(3,20)、(4,10) 和 (4,20)。由于我不知道您正在处理的数据是什么,因此我不确定确切的接近度是否重要——在这种情况下,你可以坚持使用平均值——或者你是否需要进行某种反距离加权。

    【讨论】:

      【解决方案2】:

      给定(不是 Python 代码,因为在每种情况下,第二个赋值当然会抹去第一个;-):

      y = 10
      x = [1,2,3,4,5,6]
      z = [2.3,3.4,5.6,7.8,9.6,11.2]
      
      y = 20 
      x = [1,2,3,4,5,6]
      z = [4.3,5.4,7.6,9.8,11.6,13.2]
      

      你问:“当 y = 15 x = 3.5 时,我如何找到 z 的值”?

      由于您正在查看 x 和 y 与给定“网格”完全等距的点,因此您只需取网格值之间的中点(如果您的值不等距,您将取一个成比例的中点,见后)。因此,对于 y=10,x 3 和 4 的 z 值为 5.6 和 7.8,因此对于 x 3.5,您估计它们的中点 6.7;同样对于 y=20,您估计 7.6 和 9.8 之间的中点,即 8.7。最后,由于 y=15,6.7 和 8.7 之间的中点是 z 的最终插值:7.7。

      假设您有 y=13 和 x=3.8。然后对于 x,您将采用 80% 的值,即:

      • 对于 y=10,0.2*5.6+0.8*7.8 -> 7.36

      • 对于 y=20,0.2*7.6+0.8*9.8 -> 9.46

      现在你想要这些之间的 z 30%,0.3*7.36 + 0.7*9.46 -> 8.83,这就是 z。

      这是线性插值,真的很简单。你想手动计算它,还是找到为你做的例程(例如numpy数组作为“网格”)?即使在后一种情况下,我希望这个“手动”解释(以最基本的算术术语显示你在做什么)可以帮助你理解你在做什么......;-)。

      当然,还有更高级的插值形式 - 您是否需要这些形式,或者线性插值是否足以满足您的用例?

      【讨论】:

      • 是的,谢谢,我明白了你的意思......我将需要这些例程,因为我刚刚在我收集的数据中的问题中举了一个例子,我的 y 值从 10 开始...... 300 步10 个我的 x 值是 1 ... 20 和类似的 20 个不同的 z 值,每个 y 值所以我在想是否有办法插入或推断 x 和 y 值
      【解决方案3】:

      scipy.interpolate.bisplrep

      参考: http://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.bisplrep.html

      import scipy
      import math
      import numpy
      from scipy import interpolate
      
      
      x= [1,2,3,4,5,6]
      y= [10,20,30]
      
      Y = numpy.array([[i]*len(x) for i in y])
      X = numpy.array([x for i in y])
      Z = numpy.array([[2.3,3.4,5.6,7.8,9.6,11.2],
                       [4.3,5.4,7.6,9.8,11.6,13.2],
                       [6.3,7.4,8.6,10.8,13.6,15.2]]) 
      
      tck = interpolate.bisplrep(X,Y,Z)
      print interpolate.bisplev(3.5,15,tck) 
      
      
      7.84921875
      

      编辑:

      上层解决方案并不适合您。 检查

      print interpolate.bisplev(x,y,tck)
      
      [[  2.2531746    4.2531746    6.39603175]
       [  3.54126984   5.54126984   7.11269841]
       [  5.5031746    7.5031746    8.78888889]
       [  7.71111111   9.71111111  10.9968254 ]
       [  9.73730159  11.73730159  13.30873016]
       [ 11.15396825  13.15396825  15.2968254 ]]
      

      为了克服这种插值,x 方向的 5 次多项式和 y 方向的 2 次多项式

      tck = interpolate.bisplrep(X,Y,Z,kx=5,ky=2)
      print interpolate.bisplev(x,y,tck) 
      
      [[  2.3   4.3   6.3]
       [  3.4   5.4   7.4]
       [  5.6   7.6   8.6]
       [  7.8   9.8  10.8]
       [  9.6  11.6  13.6]
       [ 11.2  13.2  15.2]]
      

      这个产量

      print interpolate.bisplev(3.5,15,tck)
      
      7.88671875
      

      绘图:
      参考http://matplotlib.sourceforge.net/examples/mplot3d/surface3d_demo.html

      fig = plt.figure()
      ax = Axes3D(fig)
      ax.plot_surface(X, Y, Z,rstride=1, cstride=1, cmap=cm.jet)
      plt.show()
      

      【讨论】:

      • 嘿,谢谢,我认为这很有效还有一个问题,我如何在 X Y z 轴上绘制它们
      • 请注意,scipy.interpolate.* (FITPACK) 样条线可能不会插值,即可能不会通过输入数据;参见平滑度参数 s。 Imho FITPACK 比 doc 更有力量,所以开始简单(Martelli):kx=ky=1, s=0。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-05
      • 2019-06-02
      • 1970-01-01
      相关资源
      最近更新 更多