Фильтрация большого файла возвращает пустой новый файл - PullRequest
0 голосов
/ 13 февраля 2020

Я новичок в python, так что простите, если этот вопрос слишком базовый c. Я пытался отфильтровать строки в большом файле (> 85 000 000 строк), используя паттерны в другом файле (около 100 000 строк). Я хочу читать эти файлы построчно для экономии памяти и записи отфильтрованных строк в другой файл. Большой файл имеет текст, такой как:

21:10433614:T:A 21  10433614    T   A   Biallelic_SNP   0.00075642965204236 0   0   0   0   0.000199680511182109
21:10433615:G:T 21  10433615    G   T   Biallelic_SNP   0.00302571860816944 0   0   0   0   0.000798722044728434
21:10433619:T:A 21  10433619    T   A   Biallelic_SNP   0   0   0.00496031746031746 0   0   0.000998402555910543
21:10433640:G:A 21  10433640    G   A   Biallelic_SNP   0   0   0   0   0.00204498977505112 0.000399361022364217
21:10433654:C:T 21  10433654    C   T   Biallelic_SNP   0   0   0   0.00397614314115308 0   0.000798722044728434
rs201609931:10434436:CAT:C  21  10434436    CAT C   Biallelic_INDEL 0.0219364599092284  0   0   0.00198807157057654 0   0.0061900958466453`7

И шаблоны такие:

21 10433614
21 10433619
21 10433654

Выходной файл должен выглядеть следующим образом:

21:10433614:T:A 21  10433614    T   A   Biallelic_SNP   0.00075642965204236 0   0   0   0   0.000199680511182109
21:10433619:T:A 21  10433619    T   A   Biallelic_SNP   0   0   0.00496031746031746 0   0   0.000998402555910543
21:10433654:C:T 21  10433654    C   T   Biallelic_SNP   0   0   0   0.00397614314115308 0   0.000798722044728434

Вот скрипт, который я использую:

paternFile = open('paterns.txt')
newFile = open('newFile.txt', 'a')
largeFile = open('largeFile.txt')
for line in largeFile:
    string = line
    for row in paternFile:
        patern = row[:-1] #to remove the end of line character
        if re.search(patern, string):
            newFile.write(string)
newFile.close()
largeFile.close()
paternFile.close()

Я тестировал его по частям, чтобы проверить, и, очевидно, он должен работать, но он не пишет в мой новый файл, и я не могу понять, почему. [РЕДАКТИРОВАТЬ] Как sugested, я проверил, что возвращает мое условие:

print(re.search(patern, string))
NONE

Я не понимаю, почему возвращается NONE вместо TRUE или FALSE. Кто-нибудь может помочь?

Ответы [ 2 ]

0 голосов
/ 13 февраля 2020

Ваша проблема в том, что файловые объекты являются итераторами. Вы можете только l oop над ними один раз, прежде чем использовать все записи. Вы проверяете шаблоны по первой строке в файле data.txt и ни по какой другой.

Вы можете сбросить то, на что смотрите в файле шаблонов, добавив

paternFile.seek(0)

после вашего for row in paternFile l oop

Таким образом, обновленный код будет выглядеть так:

paternFile = open('paterns.txt')
newFile = open('newFile.txt', 'a')
largeFile = open('largeFile.txt')
for line in largeFile:
    string = line
    for row in paternFile:
        patern = row[:-1] #to remove the end of line character
        if re.search(patern, string):
            newFile.write(string)
    paternFile.seek(0)
newFile.close()
largeFile.close()
paternFile.close()

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

0 голосов
/ 13 февраля 2020

Исходя из ваших примеров. Следующее достигло ожидаемого результата.

import re

with open('pattern.txt', 'r') as file:

     # Store patterns in a list, without \n

     patterns = [row.strip() for row in file.readlines()]

with open('data.txt', 'r') as file:

     # Store primary data in a list, without \n
     data = [row.strip() for row in file.readlines()]


with open('result.txt', 'w') as file:

     for line in data:

          # Replace ':' with ' ' to ensure the pattern can match. 
          string = line.replace(':', ' ')
          for pattern in patterns:
               if re.search(pattern, string):
                    file.write(line + '\n')

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

for line in data:
      for pattern in patterns:
           if re.search(pattern.replace(' ', '.*'), line):
                file.write(line + '\n')

Вывод:

21:10433614:T:A   21  10433614    T   A   Biallelic_SNP   0.00075642965204236 0   0   0   0   0.000199680511182109
21:10433619:T:A   21  10433619    T   A   Biallelic_SNP   0   0   0.00496031746031746 0   0   0.000998402555910543
21:10433654:C:T   21  10433654    C   T   Biallelic_SNP   0   0   0   0.00397614314115308 0   0.000798722044728434

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

...