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 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.");