Atualmente, estou tentando ler dados de arquivos .csv no Python 2.7 com até 1 milhão de linhas e 200 colunas (os arquivos variam de 100 MB a 1,6 GB). Posso fazer isso (muito lentamente) para os arquivos com menos de 300.000 linhas, mas quando vou além disso, recebo erros de memória. Meu código é parecido com este:
def getdata(filename, criteria):
data=[]
for criterion in criteria:
data.append(getstuff(filename, criteron))
return data
def getstuff(filename, criterion):
import csv
data=[]
with open(filename, "rb") as csvfile:
datareader=csv.reader(csvfile)
for row in datareader:
if row[3]=="column header":
data.append(row)
elif len(data)<2 and row[3]!=criterion:
pass
elif row[3]==criterion:
data.append(row)
else:
return data
O motivo da cláusula else na função getstuff é que todos os elementos que se enquadram no critério serão listados juntos no arquivo csv, portanto, deixo o loop quando passar por eles para economizar tempo.
Minhas perguntas são:
Como posso fazer isso funcionar com os arquivos maiores?
Existe alguma maneira de tornar isso mais rápido?
Meu computador tem 8 GB de RAM, executando o Windows 7 de 64 bits, e o processador tem 3,40 GHz (não tenho certeza de quais informações você precisa).
fonte
Respostas:
Você está lendo todas as linhas em uma lista e, em seguida, processando essa lista. Não faça isso .
Processe suas linhas conforme você as produz. Se você precisar filtrar os dados primeiro, use uma função geradora:
Também simplifiquei seu teste de filtro; a lógica é a mesma, mas mais concisa.
Como você está correspondendo apenas a uma única sequência de linhas que correspondem ao critério, você também pode usar:
Agora você pode fazer um loop
getstuff()
diretamente. Faça o mesmo emgetdata()
:Agora faça um loop diretamente
getdata()
em seu código:Você agora mantém apenas uma linha na memória, em vez de seus milhares de linhas por critério.
yield
torna uma função uma função geradora , o que significa que ela não fará nenhum trabalho até que você comece a fazer um loop sobre ela.fonte
csv.DictReader
? Porque meus testes em um arquivo .csv de 2,5 GB mostram que tentar iterar linha por linha dessa forma ao usar isso, em vez de fazercsv.reader
com que o processo Python cresça até o uso total de memória de 2,5 GB.Embora a resposta de Martijin seja provavelmente a melhor. Esta é uma maneira mais intuitiva de processar arquivos csv grandes para iniciantes. Isso permite que você processe grupos de linhas, ou pedaços, de uma vez.
fonte
Eu faço uma boa análise de vibração e vejo grandes conjuntos de dados (dezenas e centenas de milhões de pontos). Meus testes mostraram que a função pandas.read_csv () é 20 vezes mais rápida do que numpy.genfromtxt (). E a função genfromtxt () é 3 vezes mais rápida do que numpy.loadtxt (). Parece que você precisa de pandas para grandes conjuntos de dados.
Publiquei o código e os conjuntos de dados que usei neste teste em um blog discutindo MATLAB vs Python para análise de vibração .
fonte
o que funcionou para mim foi e é super rápido é
Outra solução de trabalho é:
fonte
df_train=df_train.compute()
linha em sua primeira solução não carrega o conjunto de dados inteiro na memória ... que é o que ele está tentando não fazer?Para quem chega a esta questão. Usar pandas com ' chunksize ' e ' usecols ' me ajudou a ler um arquivo zip enorme mais rápido do que as outras opções propostas.
fonte
aqui está outra solução para Python3:
aqui
datareader
está uma função geradora.fonte
Se você estiver usando o pandas e tiver muita memória RAM (o suficiente para ler todo o arquivo na memória), tente usar
pd.read_csv
comlow_memory=False
, por exemplo:fonte