Eu preciso ler um arquivo grande, linha por linha. Digamos que o arquivo tenha mais de 5 GB e preciso ler cada linha, mas obviamente não quero usá- readlines()
lo porque ele criará uma lista muito grande na memória.
Como o código abaixo funcionará para este caso? Ele xreadlines
está lendo um por um na memória? A expressão do gerador é necessária?
f = (line for line in open("log.txt").xreadlines()) # how much is loaded in memory?
f.next()
Além disso, o que posso fazer para ler isso em ordem inversa, assim como o tail
comando Linux ?
Eu encontrei:
http://code.google.com/p/pytailer/
e
" cabeça de python, cauda e verso lidas por linhas de um arquivo de texto "
Ambos funcionaram muito bem!
Respostas:
Forneci esta resposta porque o Keith, embora sucinto, não fecha o arquivo explicitamente
fonte
for
loop que itera sobre as linhas, você pode usarchunk = infile.read(chunksize)
para ler pedaços de tamanho limitado, independentemente do seu conteúdo. Você precisará procurar dentro das partes novas linhas.Tudo que você precisa fazer é usar o objeto de arquivo como um iterador.
Melhor ainda é usar o gerenciador de contexto nas versões recentes do Python.
Isso fechará o arquivo automaticamente também.
fonte
Uma abordagem da velha escola:
fonte
É melhor usar um iterador. Relevante: http://docs.python.org/library/fileinput.html
Dos documentos:
Isso evitará copiar o arquivo inteiro na memória de uma só vez.
fonte
close()
método doFileInput
objeto de classe retornado quando o loop termina - portanto, eu evitaria usá-lo dessa maneira. No Python 3.2, eles finalmente se tornaramfileinput
compatíveis com o protocolo do gerenciador de contexto que trata desse problema (mas o código ainda não seria escrito da maneira mostrada).Aqui está o que você faz se não tiver novas linhas no arquivo:
fonte
Por favor tente isto:
fonte
Eu não podia acreditar que poderia ser tão fácil quanto a resposta de @ john-la-rooy fazia parecer. Então, recriei o
cp
comando usando leitura e gravação linha por linha. É LOUCO RÁPIDO.fonte
readline
padroniza as terminações de linha, isso tem o efeito colateral de converter documentos com terminações de linha DOS em finais de\r\n
linha Unix de\n
. Meu principal motivo para pesquisar sobre este tópico foi que eu precisava converter um arquivo de log que receba uma série de terminações de linha (porque o desenvolvedor usou cegamente várias bibliotecas .NET). Fiquei chocado ao descobrir que, depois do meu teste inicial de velocidade, não precisava voltar atrás erstrip
as linhas. Já estava perfeito!O projeto blaze percorreu um longo caminho nos últimos 6 anos. Ele possui uma API simples que cobre um subconjunto útil de recursos do pandas.
O dask.dataframe cuida do chunking internamente, suporta muitas operações paralelizáveis e permite exportar fatias de volta ao pandas facilmente para operações na memória.
fonte
Aqui está o código para carregar arquivos de texto de qualquer tamanho sem causar problemas de memória. Suporta arquivos de tamanho de gigabytes
https://gist.github.com/iyvinjose/e6c1cb2821abd5f01fd1b9065cbc759d
faça o download do arquivo data_loading_utils.py e importe-o para o seu código
uso
O método process_lines é a função de retorno de chamada. Será chamado para todas as linhas, com os dados dos parâmetros representando uma única linha do arquivo por vez.
Você pode configurar a variável CHUNK_SIZE, dependendo das configurações de hardware da sua máquina.
fonte
Que tal agora? Divida seu arquivo em partes e, em seguida, leia-o linha por linha, porque quando você lê um arquivo, seu sistema operacional armazena em cache a próxima linha. Se você estiver lendo o arquivo linha por linha, não estará fazendo uso eficiente das informações em cache.
Em vez disso, divida o arquivo em partes, carregue toda a parte na memória e faça seu processamento.
fonte
Obrigado! Recentemente, eu me converti em python 3 e fiquei frustrado usando o readlines (0) para ler arquivos grandes. Isso resolveu o problema. Mas para obter cada linha, eu tive que fazer algumas etapas extras. Cada linha foi precedida por um "b", que eu acho que estava no formato binário. O uso de "decodificação (utf-8)" mudou ascii.
Então eu tive que remover um "= \ n" no meio de cada linha.
Então eu divido as linhas na nova linha.
Aqui está o código que começa logo acima de "imprimir dados" no código de Arohi.
fonte
Eu demonstrei uma abordagem de acesso aleatório no nível de bytes paralelos aqui nesta outra questão:
Obtendo o número de linhas em um arquivo de texto sem linhas de leitura
Algumas das respostas já fornecidas são boas e concisas. Eu gosto de alguns deles. Mas isso realmente depende do que você deseja fazer com os dados que estão no arquivo. No meu caso, eu só queria contar linhas o mais rápido possível em grandes arquivos de texto. Meu código pode ser modificado para fazer outras coisas também, como qualquer código.
fonte
A melhor solução que encontrei sobre isso e tentei em arquivo de 330 MB.
Onde line_length é o número de caracteres em uma única linha. Por exemplo "abcd" tem o comprimento da linha 4.
Adicionei 2 no comprimento da linha para pular o caractere '\ n' e passar para o próximo caractere.
fonte
Isso pode ser útil quando você deseja trabalhar em paralelo e ler apenas blocos de dados, mas mantê-los limpos com novas linhas.
fonte
espero que isto ajude.
fonte