【问题标题】:Nested Iteration of HDF5 using PyTables使用 PyTables 对 HDF5 进行嵌套迭代
【发布时间】:2012-12-17 23:32:24
【问题描述】:

我有一个相当大的数据集,我存储在 HDF5 中并使用 PyTables 访问。我需要在这个数据集上做的一个操作是每个元素之间的成对比较。这需要 2 个循环,一个循环遍历每个元素,一个内部循环遍历所有其他元素。因此,此操作着眼于 N(N-1)/2 次比较。

对于相当小的集合,我发现将内容转储到多维 numpy 数组中然后进行迭代会更快。由于内存问题,我遇到了大型集合的问题,并且需要在运行时访问数据集的每个元素。

将元素放入一个数组中,我每秒可以进行大约 600 次比较,而对 hdf5 数据本身进行操作,我每秒可以进行大约 300 次比较。

有没有办法加快这个过程?

示例如下(这不是我的真实代码,只是一个示例):

小套装

with tb.openFile(h5_file, 'r') as f:
    data = f.root.data

    N_elements = len(data)
    elements = np.empty((N_elements, 1e5))

    for ii, d in enumerate(data):
        elements[ii] = data['element']

D = np.empty((N_elements, N_elements))  
for ii in xrange(N_elements):
    for jj in xrange(ii+1, N_elements):             
        D[ii, jj] = compare(elements[ii], elements[jj])

大型集

with tb.openFile(h5_file, 'r') as f:
    data = f.root.data

    N_elements = len(data)        

    D = np.empty((N_elements, N_elements))  
    for ii in xrange(N_elements):
        for jj in xrange(ii+1, N_elements):             
             D[ii, jj] = compare(data['element'][ii], data['element'][jj])

【问题讨论】:

    标签: python hdf5 pytables


    【解决方案1】:

    我在这里建议两种方法:

    1. numpy memmap:创建一个内存映射数组,将数据放入其中,然后为“Small Set”运行代码。内存映射的行为几乎类似于数组。

    2. 使用多处理模块允许并行处理:如果“比较”方法至少消耗大量 CPU 时间,您可以使用多个进程。

    假设您的 CPU 中有多个内核,这将显着加快速度。使用

    • 一个从 hdf 读取数据并放入队列的进程
    • 一个进程从队列中抓取并进行比较并将一些结果放入“输出队列”
    • 一个过程再次收集结果。

    在选择方法之前:“了解你的敌人”,即使用分析!只有在瓶颈处有所改进时,优化才值得付出努力,因此首先要找出哪些方法会消耗您宝贵的 CPU 时间。

    你的算法是O(n^2),不适合大数据。您是否没有看到任何减少这种情况的机会,例如,通过应用一些逻辑?这始终是最好的方法。

    您好,

    索斯滕

    【讨论】:

    • 谢谢托尔斯滕。我之前尝试过分析代码,但老实说在解释结果时遇到了麻烦。我会再试一次。但我觉得瓶颈不应该与比较函数有任何关系,因为它在小型和大型实现中都做同样的事情。它与 PyTables 如何访问元素有关。另外,您是否看到从 O(n^2) 减少的机会?每个元素都是独一无二的,所以我看不出有什么比这更好的方法,但我可能会遗漏一些东西。
    猜你喜欢
    • 2014-09-05
    • 2013-10-03
    • 1970-01-01
    • 1970-01-01
    • 2022-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-21
    相关资源
    最近更新 更多