Как вы можете присоединиться к двум или более словарям, созданным Bio.SeqIO.index? - PullRequest
2 голосов
/ 26 октября 2011

Я хотел бы иметь возможность объединить два "словаря", хранящиеся в "indata" и "pairdata", но этот код,

indata = SeqIO.index(infile, infmt)
pairdata = SeqIO.index(pairfile, infmt)
indata.update(pairdata)

, выдает следующую ошибку:

indata.update(pairdata)
TypeError: update() takes exactly 1 argument (2 given)

Я пытался использовать,

indata = SeqIO.to_dict(SeqIO.parse(infile, infmt))
pairdata = SeqIO.to_dict(SeqIO.parse(pairfile, infmt))
indata.update(pairdata)

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

Последний вариант, который я исследовал:

indata = SeqIO.index_db(indexfile, [infile, pairfile], infmt)

, который работает отлично, но очень медленно.Кто-нибудь знает, как / могу ли я успешно соединить два индекса из первого примера выше?

Ответы [ 2 ]

2 голосов
/ 27 октября 2011

SeqIO.index возвращает доступный только для чтения словарь-подобный объект, поэтому update не будет работать с ним (извиняюсь за запутанное сообщение об ошибке; я только что исправил это в основном репозитории Biopython).*

Наилучший подход - либо использовать index_db, который будет медленнее, но должен индексировать файл только один раз, либо определить объект более высокого уровня, который действует как словарь для нескольких файлов.Вот простой пример:

from Bio import SeqIO

class MultiIndexDict:
    def __init__(self, *indexes):
        self._indexes = indexes
    def __getitem__(self, key):
        for idx in self._indexes:
            try:
                return idx[key]
            except KeyError:
                pass
        raise KeyError("{0} not found".format(key))

indata = SeqIO.index("f001", "fasta")
pairdata = SeqIO.index("f002", "fasta")
combo = MultiIndexDict(indata, pairdata)

print combo['gi|3318709|pdb|1A91|'].description
print combo['gi|1348917|gb|G26685|G26685'].description
print combo["key_failure"]
1 голос
/ 28 октября 2011

Если вы не планируете использовать индекс снова, а объем памяти не является ограничением (что в вашем случае является истинным), вы можете указать Bio.SeqIO.index_db (...) использоватьиндекс памяти SQLite3 со специальным именем индекса ": memory:" примерно так:

indata = SeqIO.index_db(":memory:", [infile, pairfile], infmt)

, где infile и pairfile - это имена файлов, а infmt - их тип формата, определенный в Bio.SeqIO (например, "fasta").

На самом деле это общий прием с библиотекой SQLite3 в Python.Для небольшого набора файлов это должно быть намного быстрее, чем создание индекса SQLite на диске.

...