具有一致输入形状的 Python 快速插值

发布于 01-18 04:08 字数 1613 浏览 2 评论 0 原文

我有一些数据位于一致的网格上,如下所示,其中每个点都有一些标量值:

Input shape

I想要将标量插入到规则网格上,如下所示:

Output shape

目前我正在使用scipy.interpolate.griddata,但是有点慢。我有 162000 个数据文件需要以完全相同的方式进行插值(将来还会有更多),因此需要更快的算法。所有数据文件都具有需要使用完全相同的网格结构进行插值的标量。

下面提供了一个简单的玩具示例:

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import griddata

inputGrid = np.array([
     [-9.00000000e+01,  4.92919128e-07],
     [-9.00000000e+01,  6.34349493e+01],
     [ 9.00000000e+01, -6.34349493e+01],
     [ 9.00000000e+01, -4.92919128e-07],
     [ 2.77323013e+01, -1.60450574e+01],
     [-2.77323013e+01,  1.60450574e+01],
     [ 1.52267699e+02, -1.60450574e+01],
     [-1.52267699e+02,  1.60450574e+01],
     [ 1.39613822e+02,  4.63530726e+01],
     [ 4.03861780e+01,  4.63530726e+01],
     [-1.39613822e+02, -4.63530726e+01],
     [-4.03861780e+01, -4.63530726e+01]])

randomScalar = np.random.random(inputGrid.shape[0])
outputGrid = np.array([[i, j] for i in np.arange(-180, 180, 30) for j in np.arange(-90, 90, 20)])
interpolatedScalar = griddata(inputGrid, randomScalar, outputGrid, method='nearest')

plt.scatter(inputGrid[:, 0], inputGrid[:, 1], c=randomScalar, s=100)
plt.scatter(outputGrid[:, 0], outputGrid[:, 1], c=interpolatedScalar, s=10)

在此处输入图像描述

我觉得我们可以利用数据的一致形状需要进行插值以显着加快速度,但我不知道是否有任何 python 函数可以利用这一优势。

具体来说,我将标量数据从 Icosphere 转换为 UV 球体。也许已经有函数可以做到这一点?我尝试过 3D 插值算法,但它们比 griddata 方法慢得多。

有什么建议吗?

I have some data that is on a consistent grid like the one bellow, where each point has some scalar value:

Input shape

I'd like to interpolate the scalars onto a regular grid like the one bellow:

Output shape

Currently I am using scipy.interpolate.griddata, but it is a bit slow. I have 162000 data files that need to be interpolated in the exact same way (and plenty more in the future), and so a much faster algorithm would be desirable. All data files have scalars that need to be interpolated with the exact same grid structure.

A simple toy example is provided bellow:

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import griddata

inputGrid = np.array([
     [-9.00000000e+01,  4.92919128e-07],
     [-9.00000000e+01,  6.34349493e+01],
     [ 9.00000000e+01, -6.34349493e+01],
     [ 9.00000000e+01, -4.92919128e-07],
     [ 2.77323013e+01, -1.60450574e+01],
     [-2.77323013e+01,  1.60450574e+01],
     [ 1.52267699e+02, -1.60450574e+01],
     [-1.52267699e+02,  1.60450574e+01],
     [ 1.39613822e+02,  4.63530726e+01],
     [ 4.03861780e+01,  4.63530726e+01],
     [-1.39613822e+02, -4.63530726e+01],
     [-4.03861780e+01, -4.63530726e+01]])

randomScalar = np.random.random(inputGrid.shape[0])
outputGrid = np.array([[i, j] for i in np.arange(-180, 180, 30) for j in np.arange(-90, 90, 20)])
interpolatedScalar = griddata(inputGrid, randomScalar, outputGrid, method='nearest')

plt.scatter(inputGrid[:, 0], inputGrid[:, 1], c=randomScalar, s=100)
plt.scatter(outputGrid[:, 0], outputGrid[:, 1], c=interpolatedScalar, s=10)

enter image description here

I feel like we could take advantage of the consistent shape that the data needs to be interpolated from to significantly speed things up, but I don't know if there are any python functions that can make use of this advantage.

Specifically, I am converting scalar data from an Icosphere onto a UV sphere. Perhaps there are functions out there that already do this? I've tried 3D interpolation algorithms, but they are much slower than the griddata approach.

Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

爱人如己 2025-01-25 04:08:49

您正在使用最近邻插值,因此我下面的答案适用于最近邻插值方法。人们可能可以应用为其他插值方法找到正确方法的技术。

如果您查看 源 < code>scipy.interpolate.griddata,你可以在"="" rel="nofollow noreferrer">第 256 行用于最近邻插值,scipy 使用名为 NearestNDInterpolator 的类(在同一文件中)。反过来,此类使用 scipy.spatial.KDTree。我们将使用该类来获取每个网格点的点的索引。按照文档中的示例并将其应用到您的玩具模型中,我们可以获得以下点,

tree = KDTree(inputGrid)
dd, ii = tree.query(outputGrid, k=1)

其中 dd 是距离(您的应用程序不需要)和 ii 是 inputGrid 中的索引。

我们现在可以使用这些索引更改您的第二个 scatter 命令:

plt.scatter(outputGrid[:, 0], outputGrid[:, 1], c=randomScalar[ii], s=10)

因此,如果您能够按预期将输入和输出网格分解为多个部分,您可以继续重新应用 ii 中的索引代码> 每个部分。

替换

You are using a nearest neighbor interpolation, and so my answer below applies to a nearest neighbor interpolation approach. One could probably apply the technique used to find the right methods for other interpolation approaches.

If you look at the source for scipy.interpolate.griddata, you can see at line 256 that for the nearest neighbor interpolation, scipy uses a class called NearestNDInterpolator (in the same file). In turn, this class gets the nearest neighbors using scipy.spatial.KDTree. We are going to use that class to get the indices of the points for each grid point. Following the example in the documentation and applying it to your toy model, we can get the points as

tree = KDTree(inputGrid)
dd, ii = tree.query(outputGrid, k=1)

where dd is the distance (which you don't need for your application) and ii is the index in inputGrid.

We can now alter your second scatter command using these indices:

plt.scatter(outputGrid[:, 0], outputGrid[:, 1], c=randomScalar[ii], s=10)

So, if you are able to predictably break up your input and output grid into sections, you can keep reapplying the indices in ii for each section.

replace

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文