【问题标题】:Reading and Operating on a HDF5 File读取和操作 HDF5 文件
【发布时间】:2013-01-23 13:26:49
【问题描述】:

我在HDF5 Example code发现了一个类似的问题
但我无法正确查看 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 的数据类型更改为对象,但这仍然没有给我数据集的确切内容。

我得到的 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  

等等。

读入数据集后,我想遍历第一列以查找特定字符串,并获取其他列中的相应元素。但我必须弄清楚这一点。

【问题讨论】:

    标签: c# hdf5


    【解决方案1】:

    对我来说,它通过简单地检查 DataSet 的实际数据类型(使用 HDFView)然后制作包含该数据类型而不是双精度的数组来工作。

    【讨论】:

      【解决方案2】:

      约翰, 如果数据集的一列填充字符串值,第二列填充双值,则该数据集由“COMPOUND”类型组成。那时事情有点复杂,(据我今天所知..我是 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...
      
        }
      

      我没有测试这段代码。它只是为您的情况从我的情况下重写的。希望这会有所帮助。

      菲利普

      【讨论】:

      • 约翰没有问这个问题。通常,您不需要像字母那样格式化答案。欢迎来到堆栈溢出!您可以点击答案下方的编辑进行更改。
      猜你喜欢
      • 1970-01-01
      • 2015-04-18
      • 1970-01-01
      • 2022-07-07
      • 2017-11-26
      • 2015-03-19
      • 1970-01-01
      • 1970-01-01
      • 2017-09-23
      相关资源
      最近更新 更多