如何将浮动的2D std向量写入HDF5文件,然后在python中读取它

时间:2015-09-08 00:36:41

标签: python c++ numpy hdf5

我想将一个浮动的2D矢量写入HDF5文件。 我使用了以下代码(writeh5.cpp):

#include <cstdlib> 
#include <ctime> 
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <H5Cpp.h>

using namespace H5;
using namespace std;

int main(void) {
  int nrow = 5;
  int ncol = 4;

  vector<vector< double > > vec2d;
  vec2d.resize(nrow, vector<double>(ncol, 0.0));

  srand((unsigned)time(0));

  typename vector< vector< double > >::iterator row;
  typename vector< double >::iterator col;
  for (row = vec2d.begin(); row != vec2d.end(); row++) {
    cout << endl;
    for (col = row->begin(); col != row->end(); col++) {

      *col = (rand()/(RAND_MAX+1.0));
      cout << *col << '\t';
    }
  }
  cout << endl;

  H5File file("test.h5", H5F_ACC_TRUNC);

  // dataset dimensions
  hsize_t dimsf[2];
  dimsf[0] = nrow;
  dimsf[1] = ncol;
  DataSpace dataspace(2, dimsf);

  DataType datatype(H5::PredType::NATIVE_DOUBLE);
  DataSet dataset = file.createDataSet("data", datatype, dataspace);

  // dataset.write(vec2d.data(), H5::PredType::NATIVE_DOUBLE);
  dataset.write(&vec2d[0][0], H5::PredType::NATIVE_DOUBLE);

  cout << endl << " vec2d has " << endl;
  for (row = vec2d.begin(); row != vec2d.end(); row++) {
      cout << endl;
      for (col = row->begin(); col != row->end(); col++) {            

        cout << *col << '\t';
      }
  }
  cout << endl;

  dataset.close();
  dataspace.close();
  file.close();

  return 0;
}

我使用g++ writeh5.cpp -I/usr/include/hdf5/ -lhdf5_cpp -lhdf5 -Wall

编译了它

一段代码产生了以下输出:

0.325553        0.598941        0.364489        0.0125061
0.374205        0.0319419       0.380329        0.815621
0.863754        0.386279        0.0173515       0.15448
0.703936        0.372486        0.728436        0.991631
0.666207        0.568983        0.807475        0.964276

文件test.h5

然后当我从python中读取此文件时(使用以下内容)

import h5py
import numpy as np

file = h5py.File("test.h5", 'r')
dataset = np.array(file["data"])

print dataset

file.close()

我得到了

 [[  3.25553381e-001   5.98941262e-001   3.64488814e-001   1.25061036e-002]
 [  0.00000000e+000   2.42092166e-322   3.74204732e-001   3.19418786e-002]
 [  3.80329057e-001   8.15620518e-001   0.00000000e+000   2.42092166e-322]
 [  8.63753530e-001   3.86278684e-001   1.73514970e-002   1.54479635e-001]
 [  0.00000000e+000   2.42092166e-322   7.03935940e-001   3.72486182e-001]]

第一行是好的,其他行是垃圾。

我尝试使用dataset.write(&vec2d[0]...dataset.write(vec2d[0].data()...,我遇到了类似的问题。

我想

  1. 使用2D std :: vector of double的内容写一个HDF5文件,
  2. 在python中读取文件并将内容存储在numpy数组中
  3. 我做错了什么?

3 个答案:

答案 0 :(得分:2)

显然,我不允许将std :: vector向量传递给write函数。因此,将向量的元素复制到静态数组可以解决问题,因为write函数很乐意接受这个数组。

然而,我对这个解决方案不满意,我期望使用这些载体 直接进入写函数。

以下是代码:

#include <cstdlib> 
#include <ctime> 
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <H5Cpp.h>

using namespace H5;
using namespace std;

int main(void) {
  int nrow = 5;
  int ncol = 4;

  vector<vector< double > > vec2d;
  vec2d.resize(nrow, vector<double>(ncol, 0.0));

  srand((unsigned)time(0));

  // generate some data
  typename vector< vector< double > >::iterator row;
  typename vector< double >::iterator col;
  for (row = vec2d.begin(); row != vec2d.end(); row++) {
    cout << endl;
    for (col = row->begin(); col != row->end(); col++) {            
        *col = (rand()/(RAND_MAX+1.0));
        cout << *col << '\t';
    }
  }
  cout << endl;

  double varray[nrow][ncol];
  for( int i = 0; i<nrow; ++i) {
    cout << endl;
    for( int j = 0; j<ncol; ++j) {
        varray[i][j] = vec2d[i][j];
    }
  }

  H5File file("test.h5", H5F_ACC_TRUNC);

  // dataset dimensions
  hsize_t dimsf[2];
  dimsf[0] = nrow;
  dimsf[1] = ncol;
  DataSpace dataspace(2, dimsf);

  DataType datatype(H5::PredType::NATIVE_DOUBLE);
  DataSet dataset = file.createDataSet("data", datatype, dataspace);

  dataset.write(varray, H5::PredType::NATIVE_DOUBLE);


  cout << endl;

 dataset.close();
 dataspace.close();
 file.close();
 return 0;
}

答案 1 :(得分:1)

这是什么?

gives

0.325553        0.598941        0.364489        0.0125061
0.374205        0.0319419       0.380329        0.815621
0.863754        0.386279        0.0173515       0.15448
0.703936        0.372486        0.728436        0.991631
0.666207        0.568983        0.807475        0.964276

我没有看到打印您的c ++代码。您是否使用其他工具阅读了该文件?

(是的,这是一个澄清的问题,但它需要太多的格式才能适应评论)。

https://stackoverflow.com/a/24622720/901925 使用Visual C ++将二维数组int [n] [m]写入HDF5文件

该解决方案涉及撰写a vector of vectors。它还讨论了编写可变长度数组。

您可能必须在数据集中写入行迭代器

for (row = vec2d.begin(); row != vec2d.end(); row++) {
      dataset.write(*row, H5::PredType::NATIVE_DOUBLE);
      # or dataset.write(row[0], ...)?
      }
  }

答案 2 :(得分:1)

当我将数据从矢量转换为动态2D数组时,我遇到了同样的问题。 h5write命令的问题不在于它不接受向量,它不理解指针数组的概念。它只能写出连续的内存。向量向量在内存中不是连续的,而是指向一堆向量的指针数组。这就是为什么当你传递数组的第一个元素时第一行是正确的。表的其余部分只是第一个向量之后的内存中的垃圾。

我的解决方案是创建一个巨大的1D向量并执行我自己的索引来回转换。这类似于h5_writedyn.c https://www.hdfgroup.org/ftp/HDF5/examples/misc-examples/h5_writedyn.c

中的方法