Хранение и перезагрузка больших многомерных наборов данных в Python - PullRequest
5 голосов
/ 21 февраля 2011

Я собираюсь запустить большое количество симуляций, производящих большое количество данных, которые необходимо сохранить и снова получить к ним доступ позже. Выходные данные из моей программы моделирования записываются в текстовые файлы (по одному на моделирование). Я планирую написать программу на Python, которая читает эти текстовые файлы, а затем сохраняет данные в формате, более удобном для последующего анализа. После долгих поисков я думаю, что страдаю от информационной перегрузки, поэтому я задаю этот вопрос в Stack Overflow для некоторых советов. Вот подробности:

Мои данные в основном примут форму многомерного массива, где каждая запись будет выглядеть примерно так:

data[ stringArg1, stringArg2, stringArg3, stringArg4, intArg1 ] = [ floatResult01, floatResult02, ..., floatResult12 ]

Каждый аргумент имеет примерно следующее число потенциальных значений:

stringArg1: 50

stringArg2: 20

stringArg3: 6

stringArg4: 24

intArg1: 10000

Обратите внимание, однако, что набор данных будет редким. Например, для заданного значения stringArg1 будет заполнено только около 16 значений stringArg2. Также для заданной комбинации (stringArg1, stringArg2) будет заполнено примерно 5000 значений intArg1. 3-й и 4-й строковые аргументы всегда полностью заполнен.

Итак, с этими числами в моем массиве будет примерно 50 * 16 * 6 * 24 * 5000 = 576 000 000 списков результатов.

Я ищу лучший способ сохранить этот массив, чтобы я мог сохранить его и открыть позже, чтобы добавить дополнительные данные, обновить существующие или запросить существующие данные для анализа. До сих пор я рассматривал три различных подхода:

  1. реляционная база данных

  2. PyTables

  3. Словарь Python, использующий кортежи в качестве ключей словаря (используя pickle для сохранения и перезагрузки)

Есть одна проблема, с которой я сталкиваюсь во всех трех подходах, я всегда заканчиваю тем, что сохранял каждую комбинацию кортежей (stringArg1, stringArg2, stringArg3, stringArg4, intArg1), либо как поле в таблице, либо как ключи в Python толковый словарь. С моей (возможно, наивной) точки зрения кажется, что в этом нет необходимости. Если бы это были целочисленные аргументы, то они просто формировали бы адрес каждой записи данных в массиве, и не было бы никакой необходимости хранить все потенциальные комбинации адресов в отдельном поле. Например, если бы у меня был массив 2x2 = [[100, 200], [300, 400]], вы бы извлекали значения, запрашивая значение в массиве адресов [0] [1]. Вам не нужно хранить все возможные адресные кортежи (0,0) (0,1) (1,0) (1,1) где-то еще. Поэтому я надеюсь найти способ обойти это.

Что бы мне хотелось сделать, это определить таблицу в PyTables, где ячейки в этой первой таблице содержат другие таблицы. Например, таблицы верхнего уровня будут иметь два столбца. Записи в первом столбце будут возможными значениями stringArg1. Каждая запись во втором столбце будет таблицей. Эти вложенные таблицы будут иметь два столбца, первый из которых будет содержать все возможные значения stringArg2, а второй - еще один столбец вложенных таблиц ...

Такое решение было бы простым для просмотра и запроса (особенно если бы я мог использовать ViTables для просмотра данных). Проблема в том, что PyTables, кажется, не поддерживает наличие в ячейках одной таблицы других таблиц. Так что, похоже, я зашел в тупик.

Я читал о хранилищах данных и подходе звездной схемы, но все же кажется, что ваша таблица фактов должна содержать кортежи всех возможных комбинаций аргументов.

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

Ответы [ 3 ]

2 голосов
/ 23 февраля 2011

Почему бы не использовать большую таблицу для хранения всех 500 миллионов записей?Если вы используете сжатие «на лету» (здесь рекомендуется использовать компрессор Blosc), большинство дублированных записей будет дедуплицировано, поэтому накладные расходы на хранение сведены к минимуму.Я бы порекомендовал попробовать это;иногда простое решение работает лучше; -)

0 голосов
/ 21 июля 2011

Я не совсем уверен в том, что вы пытаетесь сделать здесь, но похоже, что вы пытаетесь создать (потенциально) разреженный многомерный массив. Поэтому я не буду вдаваться в подробности для решения вашей конкретной проблемы, но лучший из известных мне пакетов, который справляется с этим, - Numpy Numpy . Numpy может

использоваться в качестве эффективного многомерного контейнера общих данных. Произвольные типы данных могут быть определены. Это позволяет NumPy легко и быстро интегрироваться с широким спектром баз данных.

Я много раз использовал Numpy для обработки данных моделирования, и он предоставляет много полезных инструментов, включая простое хранение / доступ к файлам.

Надеюсь, вы найдете что-то в очень простой для чтения документации:

Документация Numpy с примерами

0 голосов
/ 21 февраля 2011

Есть ли причина, по которой базовый подход за 6 столами не применим?

т.е. Таблицы 1-5 будут таблицами из одного столбца, определяющими действительные значения для каждого из полей, а затем окончательной таблицей будет таблица из 5 столбцов, определяющая записи, которые действительно существуют.

В качестве альтернативы, если каждое значение всегда существует для 3-го и 4-го строковых значений, как вы описываете, 6-я таблица может состоять только из 3 столбцов (string1, string2, int1), и вы генерируете комбинации с string3 и string4 динамически через декартову присоединиться.

...