Xarray合并两个具有不同维度长度的hdf5文件

Posted

技术标签:

【中文标题】Xarray合并两个具有不同维度长度的hdf5文件【英文标题】:Xarray to merge two hdf5 file with different dimension length 【发布时间】:2021-12-12 18:38:38 【问题描述】:

我有一些仪器数据以 hdf-5 格式保存为多个二维数组以及测量时间。如下图所示,d1d2是仪器记录不同时间的两个独立文件。它们具有相同的数据变量,唯一不同的是phony_dim_0的长度,代表了随测量时间变化的总数据点。

这些文件需要加载到仪器公司提供的特定软件中才能获得有意义的结果。我想用 Python xarray 合并多个文件,同时保持它们的原始格式,然后将一个合并的文件加载到软件中。

这是我的尝试:

files = os.listdir("DATA_PATH")
d1 = xarray.open_dataset(files[0])
d2 = xarray.open_dataset(files[1])

## copy a new one to save the merged data array.
d0 = d1

vars_ = [c for c in d1]
for var in vars_:
    d0[var].values = np.vstack([d1[var],d2[var]])

错误显示如下: replacement data must match the Variable's shape. replacement data has shape (761, 200); Variable has shape (441, 200)

我想了两个解决这个问题的方法:

    将维度长度扩展到所有合并文件的总长度。 以 d1 和 d2 的相同格式创建一个新的空数据帧。

但是,我仍然无法弄清楚实现该功能的功能。任何 cmets 或建议将不胜感激。

补充信息

数据集示例[d1],[d2]

【问题讨论】:

【参考方案1】:

我不熟悉 xarray,所以无法帮助您编写代码。但是,您不需要 xarray 来复制 HDF5 数据; h5py 旨在很好地处理作为 NumPy 数组的 HDF5 数据,并且是合并数据所需的全部内容。

关于 Xarray 的说明。它使用不同于 HDF5 和 h5py 的命名法。 Xarray 将文件称为“数据集”,并将 HDF5 数据集称为“数据变量”。 HDF5/h5py 命名法更常用,所以我将在我的帖子的其余部分使用它。

在跨 2 个或更多 HDF5 文件合并数据集时需要考虑一些事项。它们是:

    数据架构的一致性(您已检查)。 属性的一致性。如果数据集具有不同的属性名称或值,则合并过程会变得更加复杂! (您的似乎是一致的。) 最好在合并文件中创建 resizabe 数据集。这简化了过程,因为您在最初创建数据集时不需要知道总大小。更好的是,您可以稍后添加更多数据(如果/当您有更多文件时)。

我查看了您的文件。每个文件中有 8 个 HDF5 数据集。一件好事:数据集可调整大小。这简化了合并过程。此外,尽管您的数据集有很多属性,但它们似乎在两个文件中都很常见。这也简化了流程。

下面的代码通过以下步骤合并数据。

    打开新的合并文件进行写入 打开第一个数据文件(只读) 循环遍历所有数据集 一种。使用组复制功能复制数据集(数据加上maxshape参数,以及属性名称和值)。 打开第二个数据文件(只读) 循环遍历所有数据集并执行以下操作: 一种。获取 2 个数据集的大小(现有和待添加) 湾。使用.resize() 方法增加 HDF5 数据集的大小 C。将数据集中的值写入现有数据集的末尾 最后它循环遍历所有 3 个文件并打印 shapemaxshape 用于所有数据集(用于视觉比较)。

代码如下:

import h5py

files = [ '211008_778183_m.h5', '211008_778624_m.h5', 'merged_.h5' ]

# Create the merge file:
with h5py.File('merged_.h5','w') as h5fw:
    
    # Open first HDF5 file and copy each dataset.
    # Will use maxhape and attributes from existing dataset.
    with h5py.File(files[0],'r') as h5fr:            
        for ds in h5fr.keys():
            h5fw.copy(h5fr[ds], h5fw, name=ds)
                 
    # Open second HDF5 file and copy data from each dataset.
    # Resizes existing dataset as needed to hold new data.
    with h5py.File(files[1],'r') as h5fr:            
        for ds in h5fr.keys():
            ds_a0 = h5fw[ds].shape[0]
            add_a0 = h5fr[ds].shape[0]
            h5fw[ds].resize(ds_a0+add_a0,axis=0)
            h5fw[ds][ds_a0:] = h5fr[ds][:]
    
for fname in files:
    print(f'Working on file:fname')
    with h5py.File(fname,'r') as h5f:
        for ds, h5obj in h5f.items():
            print (f'for: ds; axshape=h5obj.shape, maxshape=h5obj.maxshape')

【讨论】:

以上是关于Xarray合并两个具有不同维度长度的hdf5文件的主要内容,如果未能解决你的问题,请参考以下文章

如何将 xarray DataArray 与长度为 1 的维度与更大的数组对齐?

总结 xarray 数据数组的列表

将时间序列数据存储在具有可扩展时间维度的 HDF5 中

将 70 个 netCDF 文件与 xarray 合并

[Xarray] 1. 数据结构

使用xarray加入/合并多个NetCDF文件