我想将一个500GB-800GB的密钥表转储到HDF5中,然后检索与特定密钥匹配的行。
对于HDF5文件,所有数据访问等项都使用整数" row"数字,所以似乎我必须实现行号码映射"键。在HDF5之外。
这会有用吗?我是否需要访问整个HDF5"内存(RAM)"?
任何人都可以告诉我HDF5在这种情况下会有多糟糕吗?如果有不错的索引,这只是一本庞大的字典,对吧?
我应该使用其他东西吗?
答案 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开销(因此对不适合内存的大型表使用压缩)。
使用压缩时,数据集将以块的形式拆分,并且块将被单独压缩。这意味着如果查询特定范围(行100-200),相应的压缩块将从磁盘加载到内存中,然后由内存中的CPU解压缩。与不使用压缩或连续存储数据集相比,这将加快速度。 Blosc
是元压缩器,lzf
是h5py的默认压缩器。对于Blosc
和lzf
之间的差异,请参阅此numexpr。
如果内核内查询速度不够快,您还可以在一列或多列上创建索引。这样查询将使用二进制搜索而不是顺序扫描。要在row
列的现有表上创建索引,只需运行:
indexrows = table.cols.row.create_index()
但请注意,索引不会在所有条件下使用(请参阅下面的参考资料)。要检查您的查询是否正确使用索引,可以使用thread方法。