假设您已在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开销(因此对于不适合内存的大型表使用压缩).
使用压缩时,数据集将以块的形式拆分,并且块将分别进行压缩.这意味着如果查询特定范围(行100-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
| 归档时间: |
|
| 查看次数: |
846 次 |
| 最近记录: |