python中的3D外推(基本上,scipy.griddata扩展到外推)

use*_*697 6 python interpolation numpy scipy qhull

我在scipy中使用griddata函数来插入3维和4维数据.它的作用就像一个冠军,除了它返回一堆NaN,因为我需要的一些点超出了输入数据的范围.鉴于Nd数据仅适用于"线性"模式插值,因此使用griddata进行外推而不是仅仅返回NaN应该很容易.有没有人这样做或找到了解决方法?澄清一下:我有非结构化数据,所以我不能使用任何需要常规网格的函数.谢谢!亚历克斯

np8*_*np8 5

使用 3、4 或实际上任何维度对数据进行插值和外推的一种可能性是使用scipy.interpolate.Rbf

为了方便起见,将功能get_data()plot_3d()功能附在最后。

示例数据

示例数据如下所示(第四维 w 用颜色显示)。数据间隔不规则且未网格化。

在此输入图像描述

x, y, z, w = get_data(N=200)
plot_3d(x, y, z, w)
Run Code Online (Sandbox Code Playgroud)

3d 中的插值和外推

首先,让我们设置新的 x 和 y 坐标。为了让这个更有趣,让我们外推到负 x 和负 y 方向。这形成了新的 x 和 y 感兴趣范围。

x, y, z, w = get_data(N=200)
plot_3d(x, y, z, w)
Run Code Online (Sandbox Code Playgroud)

使用scipy.interpolate.Rbf进行插值。现在,

xs = np.linspace(-10, 20) # some extrapolation to negative numbers
ys = np.linspace(-10, 20) # some extrapolation to negative numbers
xnew, ynew = np.meshgrid(xs, ys)
xnew = xnew.flatten()
ynew = ynew.flatten()
Run Code Online (Sandbox Code Playgroud)
  • 可以有任意多个变量/维度。第一个参数 ( x, y) 被视为节点的坐标。参数之前的最后一个参数function是要插值的“值”(现在:)z
  • function参数可用于控制如何对值进行插值。这会影响结果,因此请使用您的数据进行测试。
  • smooth参数可用于平滑数据中的一些噪声。如果smooth为零,则结果是插值;它将遍历您的所有数据点。如果是正值,说明数据比较平滑。这会影响结果,因此请使用您的数据进行测试。
  • 下面是结果,推断当然是错误的。这只是为了证明外推是可能的。您可能需要进行微调functionsmooth获得所需的结果。通常,数据不应被“过多”推断(如本例所示)

在此输入图像描述

添加第四维

也可以内插和外推到第四维。具体方法如下:

rbf4 = Rbf(x, y, z, w, function="thin_plate", smooth=5)
wnew = rbf4(xnew, ynew, znew)
plot_3d(xnew, ynew, znew, wnew)
Run Code Online (Sandbox Code Playgroud)
  • Rbf为第四个维度创建了另一个实例,并使用了(3d 中的插值)znew计算rbf3
  • 我将其更改function为,因为从视觉上看,该数据集的"thin_plate"表现似乎更好。
  • 结果如下: 在此输入图像描述

附录:get_dataplot_3d

出于测试目的:

import numpy as np

def get_data():
    np.random.seed(100)
    N = 200
    maxval = 20
    x = np.random.random(N) * maxval
    y = np.random.random(N) * maxval
    z = x ** 2 + np.sqrt(y) * y - y ** 3 + np.random.random(N) + 18 * y ** 2 * 2
    w = x ** 2 - np.log(y + (x * y) ** 2)
    return x, y, z, w


def plot_3d(x, y, z, w=None, show=True):
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import axes3d

    fig = plt.figure(figsize=(10, 6))
    ax = axes3d.Axes3D(fig)
    ax.scatter3D(x, y, z, c=w if not w is None else "b")
    plt.show()
Run Code Online (Sandbox Code Playgroud)


Tim*_*era 0

不太确定这是否适合您,而且尚不可用,但在 numpy 的开发版本中,有一个“pad”数组函数......

https://github.com/numpy/numpy/blob/master/numpy/lib/arraypad.py

其中一个选项是“线性斜坡”,它从边缘值开始向外推断(填充),并线性增加/减少到指定的最终值。

它是一个纯Python函数,所以你可以将它复制到你的路径中并导入(虽然未经我测试)