Как инициализировать размер столбца таблицы PyTables?

Я делаю расчет методом Монте-Карло и хочу сохранить промежуточные результаты на диск. Ниже приведена базовая версия моего кода. В моей первоначальной версии у меня был объект-агрегатор данных, который собирал результаты по каждой траектории, а затем в конце вычислял некоторую статистику и записывал на диск, но у меня начала заканчиваться память, а файлы были громоздкими. Вместо этого я пытаюсь использовать PyTables, чтобы я мог а) сбросить данные на диск и б) эффективно прочитать их обратно для дальнейшей обработки, когда это будет сделано. Я работаю с этим руководством. Моя проблема заключается в том, что для каждого запуска данные, которые будут попадать в столбец 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()

person craigim    schedule 07.02.2015    source источник


Ответы (1)


Это не полностью отвечает на мой собственный вопрос, но при решении другой проблемы я нашел решение. Вместо сохранения в таблице, как указано выше, я сохраняю вектор переменной длины в виде отдельного массива как описан здесь. Затем я сохраняю каждое скалярное значение как атрибут этого вектора.

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()
person craigim    schedule 08.02.2015