我正在进行蒙特卡罗计算,我想将中间结果保存到磁盘。以下是我的代码的基本版本。在我的原始版本中,我有一个数据聚合器对象,它将收集每个轨迹的结果,然后在最后计算一些统计信息并写入磁盘,但我开始耗尽内存,文件很笨重。我试图改为使用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()
答案 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()