如何初始化PyTables表列大小?

时间:2015-02-07 01:54:57

标签: python-3.x pytables

我正在进行蒙特卡罗计算,我想将中间结果保存到磁盘。以下是我的代码的基本版本。在我的原始版本中,我有一个数据聚合器对象,它将收集每个轨迹的结果,然后在最后计算一些统计信息并写入磁盘,但我开始耗尽内存,文件很笨重。我试图改为使用PyTables,以便我可以a)将数据刷新到磁盘上,并且b)在完成后有效地将其读回以进行进一步处理。我在this tutorial工作。我的问题是,对于每次运行,进入layer列的数据是1xn向量,其中n在脚本的开头设置(它实际上是通过命令传递的在现实生活中)。

Python不允许我在聚合器类中定义表描述符类,但是大小n超出了描述符类的范围。我来自MATLAB背景,其中所有表创建和刷新到磁盘都隐藏在单matfile命令后面,所以我真的迷失了。

我应该如何正确初始化我的数据表,以便在聚合器对象中看到它?如果我应该这样做,我怎么能对我已经工作的(除了写入磁盘)代码造成最小的损害?

import tables
import numpy

class Trajectory(tables.IsDescription):
    start = tables.Float32Col(shape=(1, 2))
    end = tables.Float32Col(shape=(1, 2))
    layer = tables.Float32Col(shape=(1, n)) # how do I pass n to here?

class AggregateResults(object):
    def __init__(self, n, filename):
        self.n = n
        self.h5 = tables.openFile(filename, mode="w")
        self.traj_group = self.h5.createGroup(self.h5.root, "Trajectories")
        self.traj_table = self.h5.createTable(self.traj_group, "trajectory", Trajectory, "Single Trajectory)

    def end_of_trajectory(self, results):
        trajectory = self.traj_table.row

        trajectory['start'] = results.start_position
        trajectory['end'] = results.end_position
        trajectory['layer'] = results.layer_path
        trajectory.append()
        trajectory.flush()

    def end_of_run(self):
        self.h5.close()


def do_code(aggregate):
    results = # long calculation goes here
    aggregate.end_of_trajectory(results)


main():
    filename = "filename.h5"
    n = 7
    aggregate = AggregateResults(n, filename)
    for x in range(100000):
        do_code(aggregate)

    aggregate.end_of_run()

1 个答案:

答案 0 :(得分:0)

这并不能完全回答我自己的问题,但在解决不同的问题时,我找到了解决方案。如上所述,我将变量长度向量保存为单独的数组described here,而不是保存在表中。然后我将每个标量值保存为该向量的属性。

class AggregateResults(object):
    def __init__(self, n, filename):
        self.n = n
        self.h5 = tables.openFile(filename, mode="w")
        self.traj_group = self.h5.createGroup(self.h5.root, "Trajectories")

    def end_of_trajectory(self, results):
        i = current_photon
        current_vector_name = "vector%2" % i
        current_vector = self.h5.create_array(self.traj_group, current_vector_name, results.layer)
        current_vector.attrs.start = results.start
        current_vector.attrs.end = results.end
        trajectory.flush()

    def end_of_run(self):
        self.h5.close()