2015-10-26 2 views
0

Так что у меня возникла проблема с извлечением текста из более крупного (> ГБ) текстового файла. Файл структурирована следующим образом:Python: способ игнорировать/учитывать новые строки с помощью read()

>header1 
hereComesTextWithNewlineAtPosition_80 
hereComesTextWithNewlineAtPosition_80 
hereComesTextWithNewlineAtPosition_80 
andEnds 
>header2 
hereComesTextWithNewlineAtPosition_80 
hereComesTextWithNewlineAtPosAAAAAAAA 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
AAAAAAAAAAAAAAAAAAAAlineAtPosition_80 
MaybeAnotherTargetBBBBBBBBBBBrestText 
andEndsSomewhereHere 

Теперь у меня есть информация, что в записи с header2 Мне нужно извлечь текст из положения X в положение Y (А в этом примере), начиная с 1 в качестве первая буква в строке под заголовком.

НО: позиции не учитывают символы новой строки. Таким образом, в основном, когда он говорит от 1 до 95, это действительно означает только буквы от 1 до 80 и следующие 15 из следующей строки.

Моим первым решением было использовать file.read (X-1), чтобы пропустить нежелательную часть спереди, а затем file.read (YX), чтобы получить часть, которую я хочу, но когда это растягивается поверх строк новой строки I доберите до нескольких символов.

Есть ли способ решить эту проблему с помощью другой функции python, чем read()? Я думал о том, чтобы просто заменить все новые строки пустыми строками, но файл может быть довольно большим (миллионы строк).

Я также попытался учесть новые строки, приняв extractLength // 80 как добавленную длину, но это проблематично в таких случаях, как пример, например, например. из 95 символов это 2-80-3 более 3 строк я на самом деле нужно 2 дополнительные позиции, но 95 // 80 равно 1.

UPDATE:

Я изменил мой код, чтобы использовать Biopython:

for s in SeqIO.parse(sys.argv[2], "fasta"): 
     #foundClusters stores the information for substrings I want extracted 
     currentCluster = foundClusters.get(s.id) 

     if(currentCluster is not None): 

      for i in range(len(currentCluster)): 

       outputFile.write(">"+s.id+"|cluster"+str(i)+"\n") 

       flanking = 25 

       start = currentCluster[i][0] 
       end = currentCluster[i][1] 
       left = currentCluster[i][2] 

       if(start - flanking < 0): 
        start = 0 
       else: 
        start = start - flanking 

       if(end + flanking > end + left): 
        end = end + left 
       else: 
        end = end + flanking 

       #for debugging only 
       print(currentCluster) 
       print(start) 
       print(end) 

       outputFile.write(s.seq[start, end+1]) 

Но я получить следующее сообщение об ошибке:

[[1, 55, 2782]] 
0 
80 
Traceback (most recent call last): 
    File "findClaClusters.py", line 92, in <module> 
    outputFile.write(s.seq[start, end+1]) 
    File "/usr/local/lib/python3.4/dist-packages/Bio/Seq.py", line 236, in __getitem__ 
    return Seq(self._data[index], self.alphabet) 
TypeError: string indices must be integers 

UPDATE2:

Измененный outputFile.write(s.seq[start, end+1]) на:

outRecord = SeqRecord(s.seq[start: end+1], id=s.id+"|cluster"+str(i), description="Repeat-Cluster") 
SeqIO.write(outRecord, outputFile, "fasta") 

и его работы :)

+1

Почему вы не используете Biopython? – jrjc

+0

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

+0

@jeanrjc У меня нет опыта работы с биопитом. Как вы это сделаете с этим? Что касается того, почему я не просто перебираю файл по строкам: текст, который я хочу извлечь, задается начальным и конечным положением, как я сказал, охватывая несколько строк и начинать/заканчивать в середине строки, но я не могу хотите всю строку. – voiDnyx

ответ

2

С Biopython:

from Bio import SeqIO 
X = 66 
Y = 130 
for s in in SeqIO.parse("test.fst", "fasta"): 
    if "header2" == s.id: 
     print s.seq[X: Y+1] 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

Biopython давайте разбора Fasta файл и получить доступ к его идентификатору, описание и последовательность легко. У вас есть объект Seq, и вы можете легко манипулировать им, не перекодируя все (например, обратное дополнение и т. Д.).

+0

Я изменил свой код, чтобы использовать biopython, но я получаю сообщение об ошибке, когда я использую ваш пример. Может быть, вы можете помочь? Я обновил свой вступительный пост. – voiDnyx

+0

моя ошибка, вы должны написать: 'outputFile.write (s.seq [start: end + 1])', а не 'outputFile.write (s.seq [start, end + 1])' – jrjc

+0

@voiDnyx, I изм. – jrjc

Смежные вопросы