读取和操作HDF5文件
本文关键字:文件 HDF5 操作 读取 | 更新日期: 2023-09-27 17:58:10
我在HDF5中发现了一个类似的问题示例代码
但我在正确查看hdf5数据集内容时遇到问题。
我正在查看的数据集包含字符串头,第一列中有字符串,其他列中有双重字符串。
以下是我的代码:
public static void readh5(string path, string filename)
{
H5.Open();
var fileID = H5F.open(path + filename, H5F.OpenMode.ACC_RDONLY);
var groupID = H5G.open(fileID, "/Example Group/");
var datasetID = H5D.open(groupID, "Events");
var dataSpace = H5D.getSpace(datasetID);
var size = H5S.getSimpleExtentDims(dataSpace);
var dataType = H5D.getType(datasetID);
double[,] dataArray = new double[size[0],11];
var wrapArray = new H5Array<double>(dataArray);
H5D.read(datasetID, dataType, wrapArray);
Console.WriteLine(wrapArray);
}
当我调试并查看wrapArray时,每个元素都是一个非常大或非常小的值,从10^300到10^-300,我不知道为什么。我不认为这些是元素的ID号。我已经尝试将wrapArray和dataArray的数据类型更改为object,但这仍然不能提供数据集的确切内容。
我得到的wrapArray的输出看起来像:
[0,0] 4.0633928641260729E+87
[0,1] 9.77854726248995E-320
[0,2] 1.52021104712121E-312
等等。
但我想要的是:
[0,0] Event1
[0,1] 2
[0,2] 56
等等。
在读取数据集后,我想循环浏览第一列以找到特定的字符串,并在其他列中获得相应的元素。但我必须弄清楚这一点。
对我来说,它的工作原理是简单地检查数据集的实际数据类型(使用HDFView),然后生成包含该数据类型的数组,而不是双重数据类型。
John,如果一个数据集有一列用字符串值填充,第二列用双值填充,则该数据集由"COMPOND"类型组成。当时事情有点复杂,(据我今天所知……我是HDF5的新手)不可能简单地将值加载到2D数组。相反,你必须:
//1) Define byte array in memory. We know that it is one string and two doubles.
//Check that string in dataset is really 256 chars long.
int rows = size[0]; //this should be number of rows in dataset.
int oneRowDataSize = 256+8+8; //string+double+double
byte[] data_to_read = new byte[oneRowDataSize * rows];
// 2) Read data to our byte array
H5D.read(datasetID, dataType, new H5Array<byte>(data_to_read));
// 3) Decompose our byte array to rows and individual values
for (int m = 0; m < rows; m++)
{
//4) offset of the row in the byte array
int pos = m*oneRowDataSize;
//5) compute individual offsets
int posString = pos;
int posDouble1 = pos + 256; //change the 256 to the correct size of string in dataset
int posDouble2 = pos + 256 + 8;
//6) convert bytes to values
string valString = Encoding.UTF8.GetString(data_to_read, posString, 256);
double valDouble1 = BitConverter.ToDouble(data_to_read, posDouble1);
double valDouble2 = BitConverter.ToDouble(data_to_read, posDouble2);
//7 And use these values for your csharp lists/arrays...
}
我没有测试这个代码。这只是我为你的案子改写的。希望这会有所帮助。
Filip