【问题标题】:3D Extrapolation in python (basically, scipy.griddata extended to extrapolate)python中的3D外推(基本上,scipy.griddata扩展为外推)
【发布时间】:2012-06-28 04:06:50
【问题描述】:

我在 scipy 中使用 griddata 函数来插入 3 维和 4 维数据。它就像一个冠军,除了它返回一堆 NaN,因为我需要的一些点超出了输入数据的范围。鉴于 N-d 数据无论如何只能与“线性”模式插值一起使用,让 griddata 进行外推而不是仅仅返回 NaN 应该是一件轻而易举的事。有没有人这样做或找到解决方法?澄清一下:我有非结构化数据,所以我不能使用任何需要常规网格的功能。 谢谢! 亚历克斯

【问题讨论】:

  • 用一些常数值填充范围外的点会有所帮助吗?在这种情况下,您可以只指定 fill_value
  • 另外,您确定要推断吗?有时,退出 NaN 并知道自己超出了范围是一个更好的选择。我使用了来自 scipy 的单变量样条曲线,它默默地推断,结果可能非常“偏离”
  • 我的情况是:我在几个点测量了一些值,然后需要通过内插/外插计算其他一些点的值。所以一个常数值,或者 NaN 真的没有帮助。我知道样条曲线的喜怒无常,所以我认为线性是一个安全的选择。不过,我想要一些适用于 N-d 数据的东西。
  • 这实际上比在这些基于三角测量的方法中看起来更重要。对于曲面细分之外的每个点,您需要选择从中推断出哪个单纯形,并且还需要一个快速算法来找到这个单纯形。此外,如果您想避免外推中的不连续性,则需要注意。然而,理清之后,线性外推就是一件简单的事情了。
  • 我将在最近的位置进行第二次运行,并用它来填补空白。谢谢!

标签: python numpy scipy interpolation qhull


【解决方案1】:

用3,4或实际上任何尺寸插入和推断数据的一种可能性是scipy.interpolate.Rbf

get_data() function和plot_3d() unify附加到结束方便。

示例数据 h2>

示例数据如下所示(第四维度,w,以颜色显示)。数据不规则间隔,而不是网格。

x, y, z, w = get_data(N=200)
plot_3d(x, y, z, w)

3D h3>中的插值和推断

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

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()

与@ 987654323插值@。现在,

from scipy.interpolate import Rbf
rbf3 = Rbf(x, y, z, function="multiquadric", smooth=5)
znew = rbf3(xnew, ynew)

plot_3d(xnew, ynew, znew)
  • 可以有多种变量/尺寸。第一个参数(@ 987654334,y)被视为节点的坐标。 function参数之前的最后一个参数是要插值的“值”(现在:z)。
  • function参数可用于控制如何插入值。 这将影响结果,以便使用您的数据玩它。 em>。
  • smooth参数可用于平滑数据的一些噪声。如果smooth为零,结果是插值;它将通过所有数据点。如果是正值,则数据更平滑。 这将影响结果,以便使用您的数据玩它。 em>。
  • 以下是结果,推断当然是糟糕的。这只是为了证明推断是可能的。您可能想要微调functionsmooth @ over event结果。通常,数据不应外推“太多”(如在这个例子中)

添加第四维度 h2>

也可以插入和推断到第四维度。这是如何:

rbf4 = Rbf(x, y, z, w, function="thin_plate", smooth=5)
wnew = rbf4(xnew, ynew, znew)
plot_3d(xnew, ynew, znew, wnew)
  • 我为第四维创建了另一个@ 987654344,我使用了使用rbf3(在3D插值)计算的@ 987654345。
  • 我改变了function 987654348 @,因为它似乎在视觉上使用这个数据集 em>来执行更好的
  • 以下结果如何看起来像:

附录: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()

【讨论】:

    【解决方案2】:

    不太确定这将为您工作,但它尚不可用,但在Numpy的开发版本中有一个'Pad'数组函数...

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

    其中一个选项是'linear_ramp',其外推动(焊盘)从边缘值开始,并线性增加/减小到指定的终端值。

    它是一个纯Python函数,所以你可以将它复制到您的路径和导入(虽然不明显)

    【讨论】:

    猜你喜欢
    • 2016-04-26
    • 1970-01-01
    • 1970-01-01
    • 2018-08-22
    • 1970-01-01
    • 1970-01-01
    • 2016-05-10
    • 2023-03-26
    • 1970-01-01
    相关资源
    最近更新 更多