首页 文章

将大量数据附加到一个表(HDF5)数据库,其中database.numcols!= newdata.numcols?

提问于
浏览
2

我试图将一个大型数据集(> 30Gb)附加到现有的pytables表 . 该表为N列,数据集为N-1列;在我知道其他N-1列之后计算一列 .

我正在使用 numpy.fromfile() 将数据集的块读入内存,然后将其附加到数据库 . 理想情况下,我想将数据粘贴到数据库中,然后计算最终列,并使用 Table.modifyColumn() 完成操作 .

我已经考虑将 numpy.zeros((len(new_data), N)) 附加到表中,然后使用 Table.modifyColumns() 来填充新数据,但我希望有人知道一种很好的方法可以避免为每个我需要追加的块生成大量的空数据 .

2 回答

  • 1

    如果列的类型相同,则可以使用 numpy.lib.stride_tricks.as_strided 使您从形状文件(L,N-1)读取的数组看起来像形状(L,N) . 例如,

    In [5]: a = numpy.arange(12).reshape(4,3)
    
    In [6]: a
    Out[6]: 
    array([[ 0,  1,  2],
           [ 3,  4,  5],
           [ 6,  7,  8],
           [ 9, 10, 11]])
    
    In [7]: a.strides
    Out[7]: (24, 8)
    
    In [8]: b = numpy.lib.stride_tricks.as_strided(a, shape=(4, 4), strides=(24, 8))
    
    In [9]: b
    Out[9]: 
    array([[  0,   1,   2,   3],
           [  3,   4,   5,   6],
           [  6,   7,   8,   9],
           [  9,  10,  11, 112]])
    

    现在您可以使用此数组 b 来填充表格 . 每行的最后一列与下一行的第一列相同,但是当您可以计算值时,您将覆盖它们 .

    如果 a 是记录数组(即具有复杂的dtype),则这将不起作用 . 为此,您可以尝试 numpy.lib.recfunctions.append_fields . 因为它会将数据复制到一个新数组,它不会为你节省大量的内存,但它可以让你一次完成所有的写操作 .

  • 1

    您可以将结果添加到另一个表 . 除非计算列与其他列相邻有一些令人信服的理由,否则这可能是最简单的 . 无论如何,将原始数据与计算分开还有待说明 .

    如果必须增加表的大小,请查看使用h5py . 它为h5文件提供了更直接的界面 . 请记住,根据h5文件中数据集的创建方式,可能无法简单地将列附加到数据中 . 有关一般数据格式的讨论,请参见http://www.hdfgroup.org/HDF5/doc/UG/03_DataModel.html中的第1.2.4节,"Dataspace" . 如果底层数据集支持h5py,则h5py支持resize .

    您还可以使用单个缓冲区来存储输入数据,如下所示:

    z = zeros((nrows, N))
    while more_data_in_file:
        # Read a data block
        z[:,:N-1] = fromfile('your_params')
        # Set the final column
        z[:,N-1:N] = f(z[:,:N-1])
        # Append the data
        tables_handle.append(z)
    

相关问题