Python/Scipy 2D插值(非均匀数据)

Sco*_*t B 16 python interpolation numpy scipy

这是我上一篇文章的后续问题:Python/Scipy Interpolation(map_coordinates)

假设我想在2d矩形区域上进行插值.我的变量'z'包含如下所示的数据.每列都是一个常量值,但是,数组的每一行可能处于不同的值,如下面的注释所示.

from scipy import interpolate
from numpy import array
import numpy as np
#                                               # 0.0000, 0.1750, 0.8170, 1.0000
z = array([[-2.2818,-2.2818,-0.9309,-0.9309],   # 0.0000, 0.0000, 0.0000, 0.0000
           [-2.2818,-2.2818,-0.9309,-0.9309],   # 0.2620, 0.2784, 0.3379, 0.3526
           [-1.4891,-1.4891,-0.5531,-0.5531],   # 0.6121, 0.6351, 0.7118, 0.7309
           [-1.4891,-1.4891,-0.5531,-0.5531]])  # 1.0000, 1.0000, 1.0000, 1.0000
# Rows, Columns = z.shape

cols = array([0.0000, 0.1750, 0.8170, 1.0000])
rows = array([0.0000, 0.2620, 0.6121, 1.0000])

sp = interpolate.RectBivariateSpline(rows, cols, z, kx=1, ky=1, s=0)

xi = np.array([0.00000, 0.26200, 0.27840, 0.33790, 0.35260, 0.61210, 0.63510,
               0.71180, 0.73090, 1.00000], dtype=np.float)
yi = np.array([0.000, 0.167, 0.815, 1.000], dtype=np.float)
print sp(xi, yi)
Run Code Online (Sandbox Code Playgroud)

作为另一种可视化方法,我知道的值数组将是:

rows = array([0.0000, 0.2620, 0.2784, 0.3379, 0.3526,
                      0.6121, 0.6351, 0.7118, 0.7309, 1.0000])
#          # 0.0000, 0.1750, 0.8170, 1.0000
z = array([[-2.2818,-2.2818,-0.9309,-0.9309],   # 0.0000
           [-2.2818,      ?,      ?,      ?],   # 0.2620,
           [      ?,-2.2818,      ?,      ?],   # 0.2784
           [      ?,      ?,-0.9309,      ?],   # 0.3379
           [      ?      ,?,      ?,-0.9309],   # 0.3526
           [-1.4891,      ?,      ?,      ?],   # 0.6121
           [      ?,-1.4891,      ?,      ?],   # 0.6351
           [      ?,      ?,-0.5531,      ?],   # 0.7118
           [      ?,      ?,      ?,-0.5531],   # 0.7309
           [-1.4891,-1.4891,-0.5531,-0.5531]])  # 1.0000
Run Code Online (Sandbox Code Playgroud)

我不知道'?' 值,它们应该插值.我尝试用None替换它们,但是然后为我的所有结果得到'nan'.

编辑:

我想我需要使用'griddata'或'interp2'.griddata似乎产生了我期望的结果,但'interp2'却没有.

from scipy import interpolate
from numpy import array
import numpy as np

z = array([[-2.2818,-2.2818,-0.9309,-0.9309],
           [-2.2818,-2.2818,-0.9309,-0.9309],
           [-1.4891,-1.4891,-0.5531,-0.5531],
           [-1.4891,-1.4891,-0.5531,-0.5531]])

rows = array([0.0000, 0.0000, 0.0000, 0.0000,
              0.2620, 0.2784, 0.3379, 0.3526,
              0.6121, 0.6351, 0.7118, 0.7309,
              1.0000, 1.0000, 1.0000, 1.0000])

cols = array([0.0000, 0.1750, 0.8180, 1.0000,
              0.0000, 0.1750, 0.8180, 1.0000,
              0.0000, 0.1750, 0.8180, 1.0000,
              0.0000, 0.1750, 0.8180, 1.0000])

xi = array([0.0000, 0.2620, 0.2784, 0.3379, 0.3526, 0.6121, 0.6351, 0.7118,
               0.7309, 1.0000], dtype=np.float)
yi = array([0.000, 0.175, 0.818, 1.000], dtype=np.float)

GD = interpolate.griddata((rows, cols), z.ravel(),
                          (xi[None,:], yi[:,None]), method='linear')
I2 = interpolate.interp2d(rows, cols, z, kind='linear')

print GD.reshape(4, 10).T
print '\n'
print I2(xi, yi).reshape(4, 10).T

import matplotlib.pyplot as plt
import numpy.ma as ma

plt.figure()
GD = interpolate.griddata((rows.ravel(), cols.ravel()), z.ravel(),
                          (xi[None,:], yi[:,None]), method='linear')
CS = plt.contour(xi,yi,GD,15,linewidths=0.5,colors='k')
CS = plt.contourf(xi,yi,GD,15,cmap=plt.cm.jet)
plt.colorbar()
plt.scatter(rows,cols,marker='o',c='b',s=5)

plt.figure()
I2 = I2(xi, yi)
CS = plt.contour(xi,yi,I2,15,linewidths=0.5,colors='k')
CS = plt.contourf(xi,yi,I2,15,cmap=plt.cm.jet)
plt.colorbar()
plt.scatter(rows,cols,marker='o',c='b',s=5)
plt.show()
Run Code Online (Sandbox Code Playgroud)

Pau*_*aul 16

看起来你明白了.

在您的上层代码示例和之前(链接)的问题中,您有结构化数据.哪个可以使用RectBivariateSpline或插值interp2d.这意味着您可以在网格上描述数据(网格上的所有点都具有已知值).网格不一定必须具有相同的dx和dy.(如果所有dx和dy都相等,你就会有一个Regular Grid)

现在,您当前的问题询问如果不知道所有要点该怎么做.这称为非结构化数据.你所拥有的只是一个领域的精选点.您不一定要构造所有顶点都具有已知值的矩形.对于这种类型的数据,您可以使用(如您所愿)griddata或者使用BivariateSpline.

现在选哪个?

与结构化最接近的类比RectBivariateSpline非结构化 BivariateSpline 类之一:SmoothBivariateSplineLSQBivariateSpline.如果要使用样条线来插入数据,请使用这些.这使得您的功能平滑且可微分,但您可以获得一个在Z.max()或Z.min()之外摆动的曲面.

由于您正在设置ky=1并且kx=1正在获得我非常确定的结构化数据的线性插值,我个人只是从RectBivariateSpline样条方案切换到结构化网格插值方案.我知道文档说它适用于常规网格,但本身的例子只是结构化的,而不是常规的. interp2d __doc__

如果您在最终切换时发现方法之间存在任何显着差异,我会很好奇.欢迎来到SciPy.

  • 如何使用结构化方法处理NaN值,特别是对于大型数组? (3认同)