Эффективные большие дикты для представления отношений M: M в Python - PullRequest
1 голос
/ 14 марта 2011

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

Эти записи - представляют отношение M: M - дваИдентификаторы (foo и bar) и некоторые простые метаданные, такие как метки времени (baz).

В некоторых foo есть слишком почти все столбцы, а в некоторых есть почти все foo.Но есть много баров, которые почти не имеют foos, и много foos, которые почти не имеют баров.

Если бы это была реляционная база данных, отношение M: M было бы смоделировано как таблица с составным ключом.Конечно, вы можете удобно искать по любому ключу компонента по отдельности.

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

Если у вас есть какой-то отсортированный индекс, вы можете использовать лексическую сортировку для итерации первого ключа в составном ключе, и вам нужен второй индекс для другого ключа;но для меня менее очевидно, к какой фактической структуре данных в стандартных коллекциях Python это равняется.

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

Существуют ли более эффективные - по скорости и в пространстве - способы сделать это? Любой тип для индексов или что-то в этом роде?


(Я хочу сохранить их на Python, потому что у меня проблемы с производительностью баз данных - как SQL, так иРазновидности NoSQL. В конечном итоге вы становитесь связанными с IPC memcpy и serialization. Это другая история, однако ключевой момент заключается в том, что я хочу переместить данные в приложение, а не получить рекомендации по их удалению из приложения;))

Ответы [ 4 ]

2 голосов
/ 14 марта 2011

Если вам нужно гибко запрашивать данные и поддерживать различные отношения, я бы посоветовал подробнее изучить базу данных, для которой существует множество вариантов.Как насчет использования базы данных в памяти, например sqlite (с использованием ": memory:" в качестве файла)?Вы на самом деле не перемещаете данные «за пределы» своей программы, и у вас будет гораздо больше гибкости, чем с многоуровневыми диктовками.

Redis также является интересной альтернативой, так как имеет другие структуры данных дляиграть, а не использовать реляционную модель с SQL.

2 голосов
/ 14 марта 2011

То, что вы описываете, звучит как разреженная матрица, где foos расположены вдоль одной оси, а столбцы - вдоль другой.Каждая непустая ячейка представляет отношение между одним foo и одним столбцом и содержит описываемые вами «простые метаданные».

Существуют эффективные пакеты разреженных матриц для Python (scipy.sparse, PySparse), на которые следует обратить внимание,Я нашел эти два просто по Googling «разреженная матрица Python».

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

2 голосов
/ 14 марта 2011

Рассматривали ли вы использование базы данных NoSQL, которая работает в памяти, например Redis ?Redis поддерживает приличное количество знакомых структур данных.

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

0 голосов
/ 12 апреля 2011

Системы NoSQL, такие как redis, не предоставляют таблицы MM.

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

class MM:
    def __init__(self):
        self._a = {} # Bs for each A
        self._b = {} # As for each B
        self._ab = {}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...