Чтение и работа с файлом HDF5

Я нашел аналогичный вопрос в Пример кода 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, и я не знаю, почему. Я не думаю, что это идентификационные номера элементов. Я попытался изменить тип данных 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  

и Т. Д.

После прочтения набора данных я хочу пройтись по первому столбцу, чтобы найти определенные строки, и получить соответствующие элементы в других столбцах. Но я должен выяснить это.


person Freddy    schedule 07.02.2013    source источник


Ответы (2)


Для меня это сработало, просто проверив фактический тип данных DataSet (используя HDFView), а затем создав массивы, содержащие этот тип данных, вместо двойников.

person Magnus    schedule 02.07.2013

Джон, если в наборе данных один столбец заполнен строковыми значениями, а второй столбец — двойными значениями, то набор данных имеет тип «СОЕДИНЕНИЕ». Тогда все немного сложнее, и (из того, что я знаю сегодня. Я новичок в 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...

  }

Я не тестировал этот код. Это было просто переписано с моего для вашего случая. Надеюсь, это поможет.

Филип

person fplesinger    schedule 22.04.2015
comment
Джон не стал задавать вопрос. И вообще не нужно оформлять ответы как письмо. Добро пожаловать в переполнение стека! Вы можете нажать «Изменить» под своим ответом, чтобы изменить его. - person Mark Bailey; 22.04.2015