当前位置: 首页 > 面试题库 >

在两个不规则网格之间进行多次插值的加速科学网格数据

欧阳炜
2023-03-14
问题内容

我在(x, y, z)要插入到新网格的同一不规则网格上定义了多个值(x1, y1, z1)。即,我有f(x, y, z), g(x, y, z), h(x, y, z),我想计算f(x1, y1, z1), g(x1, y1, z1), h(x1, y1, z1)

目前,我正在使用scipy.interpolate.griddata它,并且效果很好。但是,因为我必须分别执行每个插值并且有很多点,所以它非常慢,并且在计算中有很多重复(例如,找到最接近的点,设置网格等…)。

有没有一种方法可以加快计算速度并减少重复的计算?即沿着定义两个网格的线,然后更改插值的值?


问题答案:

每次您拨打以下电话时,都会发生几件事情scipy.interpolate.griddata

  1. 首先,调用来sp.spatial.qhull.Delaunay对不规则的网格坐标进行三角剖分。
  2. 然后,对于新网格中的每个点,都将搜索三角剖分,以找到将其放置在哪个三角形中(实际上,在哪个单形中,在您的3D情况下哪个在四面体中)。
  3. 计算每个新网格点相对于封闭单形顶点的重心坐标。
  4. 使用重心坐标和该函数在封闭单形顶点处的值,为该网格点计算一个插值。

对于所有插值,前三个步骤都是相同的,因此,如果您可以为每个新的网格点存储封闭单形顶点的索引和插值权重,则可以最大程度地减少计算量。遗憾的是,要直接使用可用功能并不容易,尽管确实有可能:

import scipy.interpolate as spint
import scipy.spatial.qhull as qhull
import itertools

def interp_weights(xyz, uvw):
    tri = qhull.Delaunay(xyz)
    simplex = tri.find_simplex(uvw)
    vertices = np.take(tri.simplices, simplex, axis=0)
    temp = np.take(tri.transform, simplex, axis=0)
    delta = uvw - temp[:, d]
    bary = np.einsum('njk,nk->nj', temp[:, :d, :], delta)
    return vertices, np.hstack((bary, 1 - bary.sum(axis=1, keepdims=True)))

def interpolate(values, vtx, wts):
    return np.einsum('nj,nj->n', np.take(values, vtx), wts)

该函数interp_weights对上面列出的前三个步骤进行计算。然后,该函数interpolate使用这些计算值非常快速地执行步骤4:

m, n, d = 3.5e4, 3e3, 3
# make sure no new grid point is extrapolated
bounding_cube = np.array(list(itertools.product([0, 1], repeat=d)))
xyz = np.vstack((bounding_cube,
                 np.random.rand(m - len(bounding_cube), d)))
f = np.random.rand(m)
g = np.random.rand(m)
uvw = np.random.rand(n, d)

In [2]: vtx, wts = interp_weights(xyz, uvw)

In [3]: np.allclose(interpolate(f, vtx, wts), spint.griddata(xyz, f, uvw))
Out[3]: True

In [4]: %timeit spint.griddata(xyz, f, uvw)
1 loops, best of 3: 2.81 s per loop

In [5]: %timeit interp_weights(xyz, uvw)
1 loops, best of 3: 2.79 s per loop

In [6]: %timeit interpolate(f, vtx, wts)
10000 loops, best of 3: 66.4 us per loop

In [7]: %timeit interpolate(g, vtx, wts)
10000 loops, best of 3: 67 us per loop

所以首先,它的作用与相同griddata,这很好。其次,设置插值,即计算vtxwts与调用大致相同griddata。但是第三,您现在几乎可以立即在同一网格上插值不同的值。

griddata此未想到的唯一事情是分配fill_value给必须外推的点。您可以通过检查至少一个权重为负的点来做到这一点,例如:

def interpolate(values, vtx, wts, fill_value=np.nan):
    ret = np.einsum('nj,nj->n', np.take(values, vtx), wts)
    ret[np.any(wts < 0, axis=1)] = fill_value
    return ret


 类似资料:
  • 问题内容: 因此,我有三个numpy数组,它们在网格上存储纬度,经度和一些属性值-也就是说,我有LAT(y,x),LON(y,x)和温度T(y,x) ),对于x和y的某些限制。网格不一定是规则的-实际上,它是三极的。 然后,我想将这些属性(温度)值插值到一堆不同的纬度/经度点上(分别存储为lat1(t),lon1(t),大约10,000 t …),这些点不属于实际的网格点。我已经尝试过matplo

  • 问题内容: 我有一个大的3d np.ndarray数据,它表示以规则网格方式在某个卷上采样的物理变量(如array [0,0,0]中的值表示物理坐标(0,0,0 ))。 我想通过在粗糙网格中插值数据来获得更好的网格间距。目前,我正在使用scipy griddata线性插值法,但速度相当慢(20x20x20数组约为90秒)。就我的目的而言,它有些过分设计,可以对体积数据进行随机采样。有没有什么可以利

  • 本文向大家介绍Three.js学习之网格,包括了Three.js学习之网格的使用技巧和注意事项,需要的朋友参考一下 前言   小编之前发布过关于几何形状和材质,相信大家看过学习之后,我们就能使用他们来创建物体了。最常用的一种物体就是网格(Mesh),网格是由顶点、边、面等组成的物体;其他物体包括线段(Line)、骨骼(Bone)、粒子系统(ParticleSystem)等。创建物体需要指定几何形状

  • 我正在使用顺风CSS,并试图建立一个网格,使某些单元格内容跨越多个单元格,而其他项目留在单个单元格。在下面的代码中,我试图展示我正在尝试完成的事情。我知道我的col-span-2班什么也没做,但我把它放在那里是为了表明我希望我能做什么。我想让所有的单元格都是相同的宽度(我只想让一些单元格内容跨越分隔线)。我需要某种覆盖逻辑吗? 感谢任何帮助。 谢谢!

  • 我想在不收缩的情况下动态添加ui节点到gridapanes行..而不是收缩gridpane应该启用滚动(网格窗格在滚动窗格中)..但它们都不是... iam所尝试的只是创建一个事件calander,该事件calander能够将整个月的事件作为天在顶部行中查看(因此至少30个colomuns) ---->控制器类包示例;

  • 我编写了这样一个代码来寻找网格步长(两个相邻的机器可表示数之间的差,机器ε,最小机器可表示数大于1和1之间的差)。为什么这个程序显示1代表巨大的价值​​关于x,以及如何修正它以显示正确答案?