使用PyTables索引500 GB HDF5文件

时间:2016-07-10 08:28:36

标签: python hdf5 pytables h5py bigdata

我想将一个500GB-800GB的密钥表转储到HDF5中,然后检索与特定密钥匹配的行。

对于HDF5文件,所有数据访问等项都使用整数" row"数字,所以似乎我必须实现行号码映射"键。在HDF5之外。

这会有用吗?我是否需要访问整个HDF5"内存(RAM)"?

任何人都可以告诉我HDF5在这种情况下会有多糟糕吗?如果有不错的索引,这只是一本庞大的字典,对吧?

我应该使用其他东西吗?

1 个答案:

答案 0 :(得分:6)

假设您已在PyTables中定义了此记录类型

class Record(tables.IsDescription):
    row = tables.Int32Col()
    col1 = tables.Int32Col()
    col2 = tables.Float64Col()
    col3 = tables.Float64Col()

常规范围查询可能如下所示:

result = [rec for rec in table if (rec['row'] > 100 and rec['row'] < 200)]

这对你的桌子来说效果不算太大。但是对于大型表,它将相对较慢,因为必须将每一行引入Python空间以评估范围条件。

为了加速这个查询,可以依赖所谓的 in-kernel 查询,这允许使用在{{{{{{{{{{{ 3}}库。

result = [rec for rec in table.where(
            'row > 100 & row < 200')]

您还可以将常规查询与内核查询混合和匹配:

result = [rec for rec in table.where(
            'row > 100 & row < 200')] if your_function(rec['col2']) ]

如果你的大表不适合内存,那么加速大约是2倍。使用压缩(即BLOSC,LZF等)会给你带来轻微的速度提升,因为解压缩的CPU开销小于I / O开销(因此对不适合内存的大型表使用压缩)。

使用压缩时,数据集将以块的形式拆分,并且块将被单独压缩。这意味着如果查询特定范围(行1​​00-200),相应的压缩块将从磁盘加载到内存中,然后由内存中的CPU解压缩。与不使用压缩或连续存储数据集相比,这将加快速度。 Blosc是元压缩​​器,lzf是h5py的默认压缩器。对于Blosclzf之间的差异,请参阅此numexpr

如果内核内查询速度不够快,您还可以在一列或多列上创建索引。这样查询将使用二进制搜索而不是顺序扫描。要在row列的现有表上创建索引,只需运行:

indexrows = table.cols.row.create_index()

但请注意,索引不会在所有条件下使用(请参阅下面的参考资料)。要检查您的查询是否正确使用索引,可以使用thread方法。

来源:Table.will_query_use_indexing()