如何在HDF5文件中筛选特定对象
我正在学习ILNumerics HDF5 API。我很喜欢用C#对象初始化器一次性设置复杂的HDF5文件的这个选项。我创建了以下文件:
using (var f = new H5File("myFile.h5")) {
f.Add(new H5Group("myTopNode") {
new H5Dataset("dsNo1", ILMath.vec<float>(1,200)), // no attributes
new H5Group("myGroup") {
new H5Dataset("dsYes", ILMath.rand(100,200)) { // matching dataset
Attributes = {
{ "att1", 1 },
{ "att2", 2 }
}
},
new H5Dataset("dsNo2") { // attributes but wrong name
Attributes = {
{ "wrong1", -100 },
{ "wrong2", -200 }
}
}
}
});
}
现在我在寻找一个聪明的方法来遍历这个文件,并筛选出具有特定属性的数据集。我想找到所有至少有一个属性名中包含“att”的数据集,并收集并返回它们的内容。这是我到目前为止做的:
IList<ILArray<double>> list = new List<ILArray<double>>();
using (var f = new H5File("myFile.h5")) {
var groups = f.Groups;
foreach (var g in groups) {
foreach (var obj in g) {
if (obj.H5Type == H5ObjectTypes.Dataset && obj.Name.Contains("ds")) {
var ds = obj as H5Dataset;
// look for attributes
foreach (var att in ds.Attributes) {
//ds.Attributes["att"].
if (att.Name.Contains("att")) {
list.Add(ds.Get<double>());
}
}
}
}
}
}
return list;
但是它并没有递归地工作。我可以调整一下,但ILNumerics声称它很方便,所以一定有更好的方法?有没有类似于Python中h5py的东西?
1 个回答
1
H5Group
提供了一个叫 Find<T>
的方法,正好能满足你的需求。这个方法会遍历整个子树,并考虑到各种条件:
var matches = f.Find<H5Dataset>(
predicate: ds => ds.Attributes.Any(a => a.Name.Contains("att")));
为什么不让你的函数返回 'ILCell' 而不是 'List' 呢?这样做可以更好地融入 ILNumerics 的内存管理(这样就不会有多余的存储空间在那儿等着垃圾回收器来处理):
using (var f = new H5File("myFile.h5")) {
// create container for the dataset contents
ILCell c = cell(size(1, 1)); // one element init
// retrieve datasets filtered
var matches = f.Find<H5Dataset>(predicate: ds => {
if (ds.Attributes.Any(a => a.Name.Contains("att"))) {
c[end + 1] = ds.Get<double>();
return true;
}
return false;
});
return c;
}
一些链接:
http://ilnumerics.net/hdf5-interface.html