Existe uma maneira eficiente de analisar blocos de texto em python?

1

Eu tenho um arquivo enorme (~ 70GB) com linhas parecidas com esta:

$ cat mybigfile.txt
5 7  
    1    1    0   -2    0    0    2
    0    4    0   -4    0    0    4
    0    0    1   -1    0    0    0
    0    0    0    0    1    0   -1
    0    0    0    0    0    1   -1
5 8  
   -1   -1   -1   -1   -1    1    1    1
    0    0    2    0    0    0   -1   -1
    3    3    3   -1   -1   -1   -1   -1
   -1   -1   -1    0    2    0    0    0
   -1    1   -1    0    0    0    1    0
5 7  
    1    1    0   -2    0    0    5
    0    2    0   -2    0    0    2
    0    0    1   -1    0    0    0
    0    0    0    0    1    0   -4
    0    0    0    0    0    1   -4
5 7  
    1    1    0   -2    0    1   -1
    0    2    0   -2    0    0    4
    0    0    1   -1    0    0    0
    0    0    0    0    1    0   -2
    0    0    0    0    0    2   -4

Eu quero dividir meu enorme arquivo em vários arquivos menos enormes organizando cada bloco pelo último caractere em seu cabeçalho. Portanto, executar $ python magic.py mybigfile.txt deve produzir dois novos arquivos v07.txt e v08.txt

$ cat v07.txt
5 7  
    1    1    0   -2    0    0    2
    0    4    0   -4    0    0    4
    0    0    1   -1    0    0    0
    0    0    0    0    1    0   -1
    0    0    0    0    0    1   -1
5 7  
    1    1    0   -2    0    0    5
    0    2    0   -2    0    0    2
    0    0    1   -1    0    0    0
    0    0    0    0    1    0   -4
    0    0    0    0    0    1   -4
5 7  
    1    1    0   -2    0    1   -1
    0    2    0   -2    0    0    4
    0    0    1   -1    0    0    0
    0    0    0    0    1    0   -2
    0    0    0    0    0    2   -4

$ cat v08.txt
5 8  
   -1   -1   -1   -1   -1    1    1    1
    0    0    2    0    0    0   -1   -1
    3    3    3   -1   -1   -1   -1   -1
   -1   -1   -1    0    2    0    0    0
   -1    1   -1    0    0    0    1    0

Os cabeçalhos de cada bloco são todos do formato 5 i com i variando de i=6 a i=22 .

Esse tipo de coisa é factível? A única linguagem que eu estou confortável o suficiente para começar é python, então eu prefiro uma solução python, se possível.

Aqui está a minha solução:

from string import whitespace
import sys


class PolyBlock(object):

    def __init__(self, lines):
        self.lines = lines

    def nvertices(self):
        return self.lines[0].split()[-1]

    def outname(self):
        return 'v' + self.nvertices().zfill(2) + '.txt'

    def writelines(self):
        with open(self.outname(), 'a') as f:
            for line in self.lines:
                f.write(line)

    def __repr__(self):
        return ''.join(self.lines)


def genblocks():
    with open('5d.txt', 'r') as f:
        block = [next(f)]
        for line in f:
            if line[0] in whitespace:
                block.append(line)
            else:
                yield PolyBlock(block)
                block = [line]


def main():
    for block in genblocks():
        block.writelines()
        sys.stdout.write(block.__repr__())


if __name__ == '__main__':
    main()

Minhas soluções percorre cada bloco e repetidamente abre e fecha os arquivos de saída. Eu suspeito que isso pode ser muito mais eficiente, mas não sei como melhorar meu código.

    
por Brian Fitzpatrick 10.02.2017 / 04:47

1 resposta

6

se você está bem com o comando awk, então tente isso ...

awk 'NF==2{filename="v0"$2".txt"}{print > filename}' mybigfile.txt
    
por 10.02.2017 / 05:09