使用Python编写HDF5文件的最快方法?

Nic*_*lko 21 python hdf5 h5py

给定一个大的(10英寸GB)混合文本/数字的CSV文件,创建具有相同内容的HDF5文件的最快方法是什么,同时保持内存使用合理?

h5py如果可能,我想使用该模块.

在下面的玩具示例中,我发现将数据写入HDF5的速度非常慢且非常快.以10,000行左右的大块写入HDF5是最佳做法吗?或者有更好的方法将大量数据写入此类文件?

import h5py

n = 10000000
f = h5py.File('foo.h5','w')
dset = f.create_dataset('int',(n,),'i')

# this is terribly slow
for i in xrange(n):
  dset[i] = i

# instantaneous
dset[...] = 42
Run Code Online (Sandbox Code Playgroud)

Mar*_*arc 7

我会避免分块数据并将数据存储为一系列单个数组数据集(沿着本杰明所建议的方式).我刚刚完成加载我正在研究HDF5的企业应用程序的输出,并且能够将大约4.5亿个复合数据类型打包为450,000个数据集,每个数据集包含10,000个数据阵列.现在写入和读取似乎是相当即时的,但是当我最初尝试分块数据时,写入和读取非常缓慢.

只是一个想法!

更新:

这些是从我的实际代码中解脱出来的一些片段(我在C与Python编码,但你应该了解我正在做的事情)并为了清晰而修改.我只是在数组中编写长无符号整数(每个数组10,000个值),并在需要实际值时读回它们

这是我典型的编剧代码.在这种情况下,我只是将长无符号整数序列写入数组序列,并在创建时将每个数组序列加载到hdf5中.

//Our dummy data: a rolling count of long unsigned integers
long unsigned int k = 0UL;
//We'll use this to store our dummy data, 10,000 at a time
long unsigned int kValues[NUMPERDATASET];
//Create the SS adata files.
hid_t ssdb = H5Fcreate(SSHDF, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
//NUMPERDATASET = 10,000, so we get a 1 x 10,000 array
hsize_t dsDim[1] = {NUMPERDATASET};
//Create the data space.
hid_t dSpace = H5Screate_simple(1, dsDim, NULL);
//NUMDATASETS = MAXSSVALUE / NUMPERDATASET, where MAXSSVALUE = 4,500,000,000
for (unsigned long int i = 0UL; i < NUMDATASETS; i++){
    for (unsigned long int j = 0UL; j < NUMPERDATASET; j++){
        kValues[j] = k;
        k += 1UL;
    }
    //Create the data set.
    dssSet = H5Dcreate2(ssdb, g_strdup_printf("%lu", i), H5T_NATIVE_ULONG, dSpace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    //Write data to the data set.
    H5Dwrite(dssSet, H5T_NATIVE_ULONG, H5S_ALL, H5S_ALL, H5P_DEFAULT, kValues);
    //Close the data set.
    H5Dclose(dssSet);
}
//Release the data space
H5Sclose(dSpace);
//Close the data files.
H5Fclose(ssdb);
Run Code Online (Sandbox Code Playgroud)

这是我的读者代码的略微修改版本.有更优雅的方法可以做到这一点(也就是说,我可以使用超平面来获得价值),但对于我相当自律的敏捷/ BDD开发流程,这是最干净的解决方案.

unsigned long int getValueByIndex(unsigned long int nnValue){
    //NUMPERDATASET = 10,000
    unsigned long int ssValue[NUMPERDATASET];
    //MAXSSVALUE = 4,500,000,000; i takes the smaller value of MAXSSVALUE or nnValue
    //to avoid index out of range error 
    unsigned long int i = MIN(MAXSSVALUE-1,nnValue);
    //Open the data file in read-write mode.
    hid_t db = H5Fopen(_indexFilePath, H5F_ACC_RDONLY, H5P_DEFAULT);
    //Create the data set. In this case, each dataset consists of a array of 10,000
    //unsigned long int and is named according to its integer division value of i divided
    //by the number per data set.
    hid_t dSet = H5Dopen(db, g_strdup_printf("%lu", i / NUMPERDATASET), H5P_DEFAULT);
    //Read the data set array.
    H5Dread(dSet, H5T_NATIVE_ULONG, H5S_ALL, H5S_ALL, H5P_DEFAULT, ssValue);
    //Close the data set.
    H5Dclose(dSet);
    //Close the data file.
    H5Fclose(db);
    //Return the indexed value by using the modulus of i divided by the number per dataset
    return ssValue[i % NUMPERDATASET];
}
Run Code Online (Sandbox Code Playgroud)

主要的内容是编写代码中的内部循环以及整数除法和mod操作,以获取数据集数组的索引和该数组中所需值的索引.让我知道这是否足够清楚,以便你可以在h5py中组合类似或更好的东西.在C中,这很简单,与分块数据集解决方案相比,显着提高了读/写时间.此外,由于我无法使用复合数据集进行压缩,因此分块的明显优势是有争议的,所以我的所有化合物都以相同的方式存储.


toi*_*ine 5

使用的灵活性numpy.loadtxt会将数据从文件中获取到中numpy array,这反过来又很适合初始化hdf5数据集。

import h5py
import numpy as np

d = np.loadtxt('data.txt')
h = h5py.File('data.hdf5', 'w')
dset = h.create_dataset('data', data=d)
Run Code Online (Sandbox Code Playgroud)