Существуют ли какие-либо деревья radix/patricia/critbit для Python?

У меня есть около 10 000 слов, используемых в качестве набора инвертированных индексов примерно для 500 000 документов. Оба нормализованы, поэтому индекс представляет собой сопоставление целых чисел (идентификатор слова) с набором целых чисел (идентификаторы документов, содержащих это слово).

В моем прототипе в качестве очевидного типа данных используется набор Python.

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

Метод Python «intersect» реализован как попарная редукция. Я думаю, что параллельный поиск отсортированных множеств может быть лучше, если библиотека предлагает быстрый способ получить следующую запись после i.

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

Я не могу найти ни одного, или, по крайней мере, ни одного с привязками Python. Существует avltree, который делает то, что я хочу, но поскольку даже парный набор слияние занимает больше времени, чем я хочу, я подозреваю, что хочу, чтобы все мои операции выполнялись на C/C++.

Знаете ли вы какие-либо библиотеки radix/patricia/critbit tree, написанные как расширения C/C++ для Python?

В противном случае, какая библиотека является наиболее подходящей, которую я должен обернуть? Сайт Judy Array не обновлялся 6 лет, а версия 1.0.5 была выпущена в мае 2007 г. (хотя он строится чисто, так что, возможно, он просто работает.)

(Редактировать: чтобы уточнить, что я ищу от API, я хочу что-то вроде:

def merge(document_sets):
    probe_i = 0
    probe_set = document_sets[probe_i]
    document_id = GET_FIRST(probe_set)

    while IS_VALID(document_id):
        # See if the document is present in all sets
        for i in range(1, len(document_sets)):
            # dynamically adapt to favor the least matching set
            target_i = (i + probe_i) % len(document_sets)
            target = document_sets[target_i]
            if document_id not in target_set:
                probe_i = target_id
                probe_set = document_sets[probe_i]
                document_id = GET_NEXT(probe_set, document_id)
                break
        else:
            yield document_id

Я ищу что-то, что реализует GET_NEXT() для возврата следующей записи, которая происходит после данной записи. Это соответствует Judy1N и аналогичным записям для других массивов Judy.

Этот алгоритм, динамически адаптирующийся к данным, должен отдавать предпочтение наборам с низким количеством совпадений. Для типа данных, с которыми я работаю, это дало 5 -10% увеличение производительности.))


person Andrew Dalke    schedule 16.01.2011    source источник
comment
На всякий случай: загляните на nltk.org, если вы еще этого не сделали.   -  person 9000    schedule 16.01.2011
comment
Я нет. Беглый просмотр не находит ничего подходящего. Можете быть более конкретными?   -  person Andrew Dalke    schedule 17.01.2011
comment
Вам действительно нужен генератор или вы в конечном итоге заинтересованы просто в получении набора/списка номеров документов?   -  person Justin Peel    schedule 17.01.2011
comment
@Justin: Все, что мне нужно, это последний набор. Пример здесь должен был показать, как я могу использовать упорядоченный набор для более быстрой функции пересечения. Без итератора в некоторых редких случаях может возвращаться пересечение 15 миллионов наборов, но это не является серьезной проблемой для моей проблемы.   -  person Andrew Dalke    schedule 17.01.2011
comment
Наборы действительно способ пойти здесь. Проблема заключается в том, как реализуются пересечения множественных наборов, так что получается (N-1) наборов. Это источник огромного замедления. Лично я бы просто сделал свою собственную (C) версию набора на основе дистрибутива Python. Я также думаю, что это должно быть запрошенным изменением в дистрибутивах Python. Какую версию Python вы используете?   -  person Justin Peel    schedule 17.01.2011
comment
@Justin: я планирую предложить/реализовать это, а также новую функцию. Также должно быть (has, has_not) = set.split(iterable), где has имеет все элементы набора, которые находятся в итерируемом, а другие элементы набора входят в has_not. Я использую 2.6 и просмотрел исходный код 2.7, чтобы увидеть его реализацию.   -  person Andrew Dalke    schedule 17.01.2011


Ответы (2)


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

BioPython имеет реализацию Trie на C.

А, вот хорошее обсуждение, включая тесты: http://bugs.python.org/issue9520

Другие (некоторые очень устаревшие) реализации:

http://pypi.python.org/pypi/radix

py-radix — это реализация структуры данных radix-дерева для хранения и извлечения сетевых префиксов IPv4 и IPv6.

https://bitbucket.org/markon/patricia-tree/src

Python-реализация patricia-tree

http://pypi.python.org/pypi/trie

Реализация префиксного дерева (trie).

http://pypi.python.org/pypi/logilab-common/0.50.3

patricia.py : Python-реализация PATRICIA trie (практический алгоритм извлечения информации, закодированной в буквенно-цифровом коде).

person TryPyPy    schedule 16.01.2011
comment
Trie Biopython не поддерживает получение следующей записи после i в API. Radix предназначен специально для адресов в формате IPv4/6, а не является библиотекой общего назначения. Trie - это (как вы говорите) чистый Python, и у него нет интерфейса get next. patricia.py явно отсутствует в репозитории logilab. - person Andrew Dalke; 17.01.2011

Недавно я добавил поддержку итераций в datrie, вы можете попробовать.

person Mikhail Korobov    schedule 27.07.2012
comment
К сожалению, у меня происходит сбой, python 3.3, 32-разрядная версия win7, дата 0.4.2, я пытаюсь запустить пример кода, приведенный на странице github. :-/ - person laurasia; 25.11.2012
comment
Сбой приложения при загрузке данных: c0000374, похоже на повреждение кучи. - person laurasia; 26.11.2012
comment
Не могли бы вы запустить проблему в системе отслеживания ошибок? Правильно ли установлен алфавит? - person Mikhail Korobov; 26.11.2012
comment
Насколько я помню, я установил «abcdef» в качестве алфавита и добавил только t['a'] = 'a', t['b'] = 'b' и т. д., где t - это Trie. Я постараюсь уточнить это в ближайшее время, я удалил datrie сейчас и установлю его сегодня вечером снова. Я использую mingw 4.6.2 win32 для компиляции. - person laurasia; 28.11.2012