使用PyTables索引500 GB HDF5文件

Sha*_*ang 0 python hdf5 bigdata pytables h5py

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

对于HDF5文件,像所有数据访问这样的项使用整数"行"数字,所以我似乎必须在HDF5之外实现"行号键映射".

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

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

我应该使用其他东西吗?

Ümi*_*mit 6

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

class Record(tables.IsDescription):
    row = tables.Int32Col()
    col1 = tables.Int32Col()
    col2 = tables.Float64Col()
    col3 = tables.Float64Col()
Run Code Online (Sandbox Code Playgroud)

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

result = [rec for rec in table if (rec['row'] > 100 and rec['row'] < 200)]
Run Code Online (Sandbox Code Playgroud)

这个工作正常,你的表不是太大.但是对于大型表,它将相对较慢,因为必须将每一行引入Python空间以评估范围条件.

为了加速这个查询,可以依赖所谓的内核内查询,它允许使用在C 语言库中借助于C编写的PyTables内核来检查条件.

result = [rec for rec in table.where(
            'row > 100 & row < 200')]
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

indexrows = table.cols.row.create_index()
Run Code Online (Sandbox Code Playgroud)

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

资料来源:http://www.pytables.org/usersguide/optimization.html#indexed-searches