Эффективная группировка параллельных массивов / векторов в Python
У меня есть очень большой набор данных в формате ROOT (двоичный), содержащий сериализованные объекты std::vector. Каждый вектор длины N по существу представляет элемент данных набора из N логических объектов (здесь N может варьироваться в зависимости от каждой записи в файле). Например, для каждой записи в файле я читаю следующие объекты:
std::vector<float> foo_a;
std::vector<float> foo_b;
std::vector<int> foo_c;
Логически, эти параллельные поля представляют объект. Я хочу иметь возможность обрабатывать данные, как если бы у меня было это вместо этого:
struct Foo {
float a;
float b;
int c;
};
std::vector<Foo> my_foos;
Так что, например, если я хочу удалить определенный "Foo" из списка или преобразовать его на месте и т. Д., Мне не нужно отслеживать все его параллельные элементы данных, чтобы внести изменения.
Я получаю доступ к сериализованным объектам через Python, используя библиотеку, которая просто передает pythonized объекты std::vector для каждой записи, которую я запрашиваю. Технически, одни и те же векторы сохраняются в памяти при доступе к файлу; они очищаются и пополняются новыми данными из каждой записи. Вот набросок того, как я сейчас возражаю:
class Dummy:
def __init__(self): pass
def get_objects(list_of_field_names, list_of_parallel_vectors):
names_and_vectors = zip(list_of_field_names, list_of_parallel_vectors)
n = len(list_of_parallel_vectors[0])
for i in xrange(n):
obj = Dummy()
obj_members = [(field_name, vector.at(i))
for field_name, vector in names_and_vectors]
obj.__dict__.update(obj_members)
yield obj
# ...
# get the std::vectors from file:
foo_a, foo_b, foo_c = magic()
# retrieve my python list of Foo objects:
objects_to_process = get_objects( ('a','b','c'), (foo_a, foo_b, foo_c) )
# now I can access logical data in the parallel vectors as a python object:
for obj in objects_to_process:
print (obj.a + obj.b) / obj.c
После профилирования я обнаружил, что все накладные расходы на создание объектов и копирование данных из векторов в объекты Python являются существенным узким местом во времени обработки. Есть ли более эффективный способ добиться того же эффекта?
Приветствуются принципиальные и мудрые советы относительно опасностей оптимизации или более мудрых способов кожи этого кота, но имейте в виду, что: 1) наборы данных огромны (до 100 ТБ); Есть миллионы записей и тысячи параллельных векторов различной длины (соответствующих десяткам логических объектов). 2) Я не имею никакого контроля над форматом входных данных.