假设你已经在 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查询,它允许在@987654321 的帮助下使用用C 编写的PyTables 内核检查条件@ 图书馆。
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 之间的区别,请参阅此thread。
如果内核查询速度不够快,您还可以在一列或多列上创建索引。这样,查询将使用二进制搜索而不是顺序扫描。要在现有表上为 row 列创建索引,只需运行:
indexrows = table.cols.row.create_index()
但请注意,索引不会在所有条件下都使用(请参阅下面的参考资料)。要检查您的查询是否正确使用索引,您可以使用Table.will_query_use_indexing() 方法。
来源:http://www.pytables.org/usersguide/optimization.html#indexed-searches