从保留形状的现有数据集创建新的HDF5数据集



我是HDF5的新手,我正试图从现有的数据集创建一个新的数据集,其中新的数据集是现有数据集中每个变量的单个文件。我使用以下代码

f = h5py.File(filename,'r')
parts = [part for part in f.keys() if 'var' in part]
stats = f['stats'][()].decode()
cfg = Inifile(stats)
fields = cfg.get('data', 'fields', '').split(',')
fnew = {}
for field in fields:
fnew[field] = h5py.File(filename+'_'+field, "w")
cfg.set('data', 'fields', field)
newstats = cfg.tostr()
fnew[field].create_dataset('stats', data=newstats)
for part in parts:
for i, field in enumerate(fields):
fnew[field].create_dataset(part, data=f[part][:,i,:])

旧数据集中的对象是三维的,例如[NX,NV,NY],而新数据集中的对象是二维的[NX,NY]。但是,我希望它们是三维的[NX,1,NY],以便它们与其他代码兼容。我如何使用HDF5/h5py库做到这一点?

您发布的代码中有很多内容。你的问题仅仅是关于重塑最后几行数据吗?

for part in parts:
for i, field in enumerate(fields):
fnew[field].create_dataset(part, data=f[part][:,i,:])

如果是,下面是简短的回答:

for part in parts:
(a0, a1, a2) = f[part].shape
for i, field in enumerate(fields):
fnew[field].create_dataset(part, data=f[part][:,i,:].reshape(a0,1,a2))

过程中的关键概念如下:

  • h5py数据集的行为类似于NumPy数组,所以你可以读取数据片,获得.shape属性等。
  • 使用h5_dataset.shape获取数据形状
  • [:,index,:]
  • 从数据集中读取数据片
  • 使用.reshape()重塑每个切片到所需的[NX,1,NY]

我很好奇,你为什么要创建数据的副本?没有必要那样做。简单地读取数据集的切片并为下游计算重塑。一旦您知道如何操作NumPy数组(和h5py数据集对象),这很容易做到。

注意:您忘记包含f.close(),这会使您的文件处于确定状态。我更喜欢Python的with -- as:上下文管理器来打开文件。如果/当with代码块中出现异常(错误),它将在完成时关闭文件。

在处理HDF5文件时,在编写代码之前理解数据模式是很重要的。我创建了一个示例来展示一般过程。它读取形状为[NX,NV,NY]的数据,然后复制为形状为[NX,1,NY]的'NV'数据集。一旦你理解了这个概念,它就可以适用于任何模式。

下面的例子首先创建一个简单的文件,其中一个形状为[NX,NV,NY]的数据集(第一个with/as块)。然后,在第二个with/as块中,从第一个文件中的数据集读取数据片并复制到一个新文件(也可以是第一个文件中的新数据集)。使用reshape()将每个数据片写入形状为[NX,1,NY]的单独数据集。

示例代码:

# Create a test file
filename='SO_69101523.h5'
with h5py.File(filename,'w') as f1:
nx, nv, ny = 100, 10, 100
arr = np.random.random(nx*nv*ny).reshape(nx,nv,ny)
f1.create_dataset('var01',data=arr)
newfilename='SO_69101523_new.h5'
# open existing file as f1 and 
# new file as f2     
with h5py.File(filename,'r') as f1, 
h5py.File(newfilename,'w') as f2:
part = 'var01'
ds1 = f1[part] 
print(ds1.shape)  #shows (100, 10, 100) from above
a0, a2 = ds1.shape[0], ds1.shape[2]
for a1 in range(ds1.shape[1]):
ds_name = f'{part}_{a1:03}'
f2.create_dataset(ds_name,data=ds1[:,a1,:].reshape(a0,1,a2))
print(f2[ds_name].shape)

相关内容

  • 没有找到相关文章

最新更新