如何读取成分未知的 HDF5 复合数据类型?

问题描述 投票:0回答:1

我已经成功使用

hdf5
crate(如下所示)将 HDF5 数据读取到 Rust 中。但这种方法依赖于事先了解数据集的确切结构。

在数据中,我尝试读取列标题名称保持一致,但顺序可能会有所不同,有些可能存在或不存在。目前所有列都是

f64
,这样就简化了问题。

理想情况下,我正在进行的处理需要将数据最终放入哈希图向量中

Vec<HashMap<String, f64>>
或反转也可以工作
HashMap<String, Vec<f64>>
。其中关键是列标题。

即使只是将数据集的每一行作为二进制读取,然后使用

descriptor
对其进行转换也可以。我似乎找不到使用该库执行此操作的方法。有没有办法在不求助于 C HDF 库的情况下做到这一点?

    use hdf5::*;
    #[derive(H5Type, Clone, PartialEq, Debug)] // register with HDF5
    #[repr(C)]
    struct Wrap {
        time: f64,
        px: f64,
        py: f64,
        pz: f64,
        r: f64,
        u: f64,
    };

    let file = File::open("file_1.hdf")?;
    let ds = file.dataset("object")?;
    let data_type = ds.dtype()?;
    let descriptor = data_type.to_descriptor()?;

    let data: Vec<Wrap> = ds.read_raw()?;
rust hdf5 hdf
1个回答
0
投票

如果其他人有同样的问题,如果我想我会发布我最终做了什么。我找不到一种方法来单独使用板条箱的高级部分来完成此操作,因此我只使用了 Rust HDF 板条箱的片段和 hdf5_sys 公开的外部 c 函数包装器(由 hdf5 板条箱安装)。

获取一列数据的代码应该如下所示:

use hdf5::*;
use hdf5::types::*;
use hdf5::globals::*;
use hdf5_sys::{h5s, h5p, h5d, h5t};

let name_file = String::from("file_name.h5");
let name_ds = "dataset_name";
let name_col = "col_name";

let file = File::open(name_file).expect("Could not open given HDF file.");
let ds = file.dataset(name_ds).expect("Could not open dataset.");
let buffer = &mut [0.0_f64; 1000]; 
let name = to_cstring(name_col.as_ref()).unwrap();
let ds_id = self.ds.id();

unsafe{
    let dt_id = h5t::H5Tcreate(h5t::H5T_class_t::H5T_COMPOUND, 8);
    h5t::H5Tinsert(dt_id, name.as_ptr(), 0, *H5T_NATIVE_DOUBLE);
    h5d::H5Dread(ds_id, dt_id, h5s::H5S_ALL, h5s::H5S_ALL, h5p::H5P_DEFAULT, buffer.as_mut_ptr().cast());
}

let buffer_vec = buffer.to_vec();

pub fn to_cstring<S: Borrow<str>>(string: S) -> Result<CString> {
    let string = string.borrow();
    #[allow(clippy::map_err_ignore)]
    CString::new(string).map_err(|_| format!("null byte in string: {string:?}").into())
}

这显然不是生产级别的代码,但它应该可以帮助任何寻找前进道路的人。

注意。如果您不知道列的数据类型,您可以使用以下方法获取列描述符:

let data_type = ds.dtype().expect("Could not find datatype.");
let descriptor = data_type.to_descriptor().expect("Could not ascertain datatype descriptor.");
© www.soinside.com 2019 - 2024. All rights reserved.