【问题标题】:How can I solve this 3D regular grid interpolation problem如何解决这个 3D 规则网格插值问题
【发布时间】:2019-01-12 20:07:01
【问题描述】:

我是一个新的 python 用户。我有一个 h5 文件,它是固定红移时引力势的快照。我已经阅读了 python 中的 h5 文件,现在我想编写一个代码,该代码将通过使用三线性插值来给出 (x, y, z) 给定值的重力势值。你们中的任何人都可以帮我这样做吗?为了您的好意,代码如下:

In [1]: import numpy as np

In [2]: import h5py

In [3]: from scipy.interpolate import RegularGridInterpolator

In [4]: f = h5py.File('my.h5', 'r')

In [5]: list(f.keys())
Out[5]: [u'data']

In [6]: data = f[u'data']

In [7]: data.shape
Out[7]: (64, 64, 64)

In [8]: data.dtype
Out[8]: dtype(('<f8', (3,)))

In [9]: data[0:63, 0:63, 0:63]
Out[9]: 
array([[[[ 7.44284016e-09, -3.69665900e-09,  8.75937447e-10],
         [ 8.00073078e-09, -2.62747161e-09,  9.82415717e-11],
         [ 7.81088465e-09, -2.03862452e-09, -4.00492778e-10],
         ...,
         [ 4.98376989e-09, -3.97621746e-09,  2.25554383e-09],
         [ 5.54899844e-09, -4.09876187e-09,  2.01146743e-09],
         [ 6.03652599e-09, -4.03159468e-09,  1.47328647e-09]],..............................

假设,我想通过使用#RegularGridInterpolator 函数找到点 (4.98376989e-09, -3.97621746e-09, 2.25554383e-09) 的电位值。我该怎么做?

【问题讨论】:

  • RegularGridInterpolator() 有 2 个主要输入:1) 用于定义网格的点元组,以及 2) 每个网格的值数组。如果我理解您的示例 data 是一个网格点数组。您需要将其切成 3 个数组 (x,y,z) 并作为元组引用。值数组在哪里定义? scipy 文档有一个简单的例子,阐明了每个变量的使用。
  • docs 的哪一部分你不理解?
  • 非常感谢您的评论。我不明白这部分文档: >>> from scipy.interpolate import RegularGridInterpolator >>> def f(x,y,z): ... return 2 * x3 + 3 * y2 - z >>> x = np.linspace(1, 4, 11) >>> y = np.linspace(4, 7, 22) >>> z = np.linspace(7, 9, 33) >>> 数据 = f(*np.meshgrid(x, y, z, indexing='ij', sparse=True))。因为我已经有了一个数据集,所以这里有必要定义 (x, y, z) 吗?如何制作数据集的切片?你能推荐我吗?
  • 语句x/y/z= np.linspace( ) 填充了定义网格的3 个数组。这些是空间中的位置(例如 x、y、z 一起定义坐标)。 data=f( ) 在关联的 x/y/z 位置创建一组值。如果我理解您的问题,您从 HDF5 文件中提取为data 的数据集就是您的values(与示例相同)。正确的?如果是这样,定义这些值位置的 x/y/z 值在哪里?这就是您需要的部分。
  • @Photon-你还在解决这个问题吗?我的回答有意义吗?我认为您需要查看所有数据集以找到具有网格定义的数据集。

标签: python scipy interpolation h5py pytables


【解决方案1】:

这是一个足够有趣(也很棘手)的问题,我认为它值得一个答案来演示使用 HDF5 文件中的数据的 scipy 插值示例。下面有 2 个代码部分。

  1. 第一个使用网格定义填充 HDF5 文件,然后 插值中使用的 mesh_data。

  2. 第二个打开步骤 1 中的 HDF5 文件,并将 x,y,z, mesh_data 数据集作为示例中使用的 Numpy 数组读取。

运行此代码以创建 HDF5 文件:

import numpy as np
import h5py

def f(x,y,z):
   return 2 * x**3 + 3 * y**2 - z

x = np.linspace(1, 4, 11)
y = np.linspace(4, 7, 22)
z = np.linspace(7, 9, 33)
mesh_data = f(*np.meshgrid(x, y, z, indexing='ij', sparse=True))

h5file = h5py.File('interpolate_test.h5', 'w')
h5file.create_dataset('/x', data=x)
h5file.create_dataset('/y', data=y)
h5file.create_dataset('/z', data=z)
h5file.create_dataset('/mesh_data', data=mesh_data)

h5file.close()

然后,运行此代码以使用 h5py 读取 HDF5 文件并进行插值:

import numpy as np
from scipy.interpolate import RegularGridInterpolator
import h5py

h5file = h5py.File('interpolate_test.h5')

x = h5file['x'][:]
y = h5file['y'][:]
z = h5file['z'][:]
mesh_data = h5file['mesh_data'][:,:,:]

my_interpolating_function = RegularGridInterpolator((x, y, z), mesh_data)

pts = np.array([[2.1, 6.2, 8.3], [3.3, 5.2, 7.1]])
print (my_interpolating_function(pts))

结果输出应该如下所示(与 scipy 示例相同):

[125.80469388 146.30069388]

对于那些使用 Pytables API 读取 HDF5 数据的用户,这里是上面第 2 步的替代方法。读取数据的过程类似,只是调用不同。

运行此代码以使用 Pytables 读取 HDF5 文件并进行插值:

import numpy as np
from scipy.interpolate import RegularGridInterpolator
import tables

h5file = tables.open_file('interpolate_test.h5')

x = h5file.root.x.read()
y = h5file.root.y.read()
z = h5file.root.z.read()
mesh_data = h5file.root.mesh_data.read()

my_interpolating_function = RegularGridInterpolator((x, y, z), mesh_data)

pts = np.array([[2.1, 6.2, 8.3], [3.3, 5.2, 7.1]])
print (my_interpolating_function(pts))

结果输出应该与上面相同(以及 scipy 示例):

[125.80469388 146.30069388]

【讨论】:

  • 我突然想到有些人可能想使用 Pytables 来读取 HDF5 数据。有关使用 Pytables 完成的第 2 步,请参见下文。
  • 是否可以获得存储在 hdf 文件中的整个数据集的插值结果?或者,是否可以自动更新 pts 而无需提及? @kcw78
  • 我的示例在 h5 文件中有 4 个数据集,用于定义插值网格坐标(x,y,z 数据集)和这些点的数据值(mesh_data 数据集)。如果您有另一个 X/Y/X 点数据集进行插值,请按照上面代码中的最后 2 个步骤操作。将坐标加载到 np.array(类似于上面的 pts)并调用 my_interpolating_function(pts) 并返回值。返回的数组包含您的插值结果。要保存,请使用create_dataset 将数据写入 h5 文件,如上述创建 HDF5 文件步骤所示。
猜你喜欢
  • 2019-12-18
  • 2012-12-29
  • 2011-07-27
  • 1970-01-01
  • 2014-03-08
  • 2020-07-19
  • 1970-01-01
  • 2013-03-13
  • 2023-03-10
相关资源
最近更新 更多