Estou tentando ler um arquivo csv grande (aprox. 6 GB) no pandas e estou recebendo um erro de memória:
MemoryError Traceback (most recent call last)
<ipython-input-58-67a72687871b> in <module>()
----> 1 data=pd.read_csv('aphro.csv',sep=';')
...
MemoryError:
Alguma ajuda nisso?
Respostas:
O erro mostra que a máquina não possui memória suficiente para ler o CSV inteiro em um DataFrame de uma só vez. Supondo que você não precise do conjunto de dados inteiro na memória de uma só vez, uma maneira de evitar o problema seria processar o CSV em partes (especificando o
chunksize
parâmetro):O
chunksize
parâmetro especifica o número de linhas por bloco. (O último pedaço pode conter menos dechunksize
linhas, é claro.)fonte
DF.append(chunk)
dentro do loop. Isso usaráO(N^2)
operações de cópia. É melhor acrescentar os dados agregados a uma lista e criar o DataFrame a partir da lista com uma chamada parapd.DataFrame
oupd.concat
(dependendo do tipo de dados agregados).DF.append(chunk)
em um loop requerO(N^2)
operações de cópia ondeN
é o tamanho dos pedaços, porque cada chamadaDF.append
retorna um novo DataFrame. Ligarpd.DataFrame
oupd.concat
uma vez fora do loop reduz a quantidade de cópias paraO(N)
.chunksize
parâmetro se refere ao número de linhas por bloco. O último pedaço pode conter menos dechunksize
linhas, é claro.pd.concat([list_of_dfs])
uma vez após o loop é muito mais rápido do que chamarpd.concat
oudf.append
muitas vezes dentro do loop. Obviamente, você precisará de uma quantidade considerável de memória para armazenar o csv inteiro de 6 GB como um DataFrame.Chunking nem sempre deve ser a primeira porta de escala para esse problema.
O arquivo é grande devido a dados não numéricos repetidos ou a colunas indesejadas?
Nesse caso, às vezes você pode obter uma economia de memória massiva lendo as colunas como categorias e selecionando as colunas necessárias por meio do
usecols
parâmetro pd.read_csv .Seu fluxo de trabalho exige fatiar, manipular e exportar?
Nesse caso, você pode usar o dask.dataframe para fatiar, executar seus cálculos e exportar iterativamente. O chunking é executado silenciosamente pelo dask, que também suporta um subconjunto da API do pandas.
Se tudo mais falhar, leia linha por linha através de blocos.
Pedaço via pandas ou via biblioteca csv como último recurso.
fonte
Eu procedi assim:
fonte
read_csv
pararead_table
?Para dados grandes, recomendo que você use a biblioteca "dask",
por exemplo:
Você pode ler mais na documentação aqui .
Outra ótima alternativa seria usar o modin, porque toda a funcionalidade é idêntica à dos pandas, mas aproveita as bibliotecas de quadros de dados distribuídos, como o dask.
fonte
A resposta acima já está satisfazendo o tópico. De qualquer forma, se você precisar de todos os dados da memória - dê uma olhada no bcolz . Está comprimindo os dados na memória. Eu tive uma experiência muito boa com isso. Mas faltam muitos recursos de pandas
Edit: Eu tenho taxas de compressão em torno de 1/10 ou tamanho orig, eu acho, é claro, dependendo do tipo de dados. Recursos importantes ausentes foram agregados.
fonte
chunks
método mencionado e usar o bcolz se precisar de todos os dados na memória para fazer uma análise. Apenas um pensamento.Você pode ler os dados como pedaços e salvar cada pedaço como picles.
Na próxima etapa, você lerá os picles e anexará cada picles ao quadro de dados desejado.
fonte
df
se encaixa inteiramente na memória (como implícita) e contém a mesma quantidade de dados que a sua entrada, certamente você não precisa dividir nada?As funções read_csv e read_table são quase as mesmas. Mas você deve atribuir o delimitador “,” ao usar a função read_table no seu programa.
fonte
Solução 1:
Usando pandas com grandes dados
Solução 2:
fonte
dfList.append
, apenas processar cada pedaço (df
) separadamenteSegue um exemplo:
fonte
Você pode tentar o sframe, que tem a mesma sintaxe que os pandas, mas permite manipular arquivos maiores que a sua RAM.
fonte
Se você usa pandas, lê grandes arquivos em partes e depois produz linha por linha, eis o que eu fiz
fonte
Desejo fazer uma resposta mais abrangente com base na maioria das soluções possíveis que já são fornecidas. Também quero apontar mais uma ajuda potencial que pode ajudar no processo de leitura.
Opção 1: tipos
"dtypes" é um parâmetro bastante poderoso que você pode usar para reduzir a pressão de memória dos
read
métodos. Veja esta e esta resposta. Os pandas, por padrão, tentam inferir tipos de dados.Referindo-se a estruturas de dados, todos os dados armazenados, uma alocação de memória ocorre. Em um nível básico, consulte os valores abaixo (A tabela abaixo ilustra os valores da linguagem de programação C):
Consulte esta página para ver a correspondência entre os tipos NumPy e C.
Vamos dizer que você tem um array de inteiros de dígitos . Você pode atribuir teoricamente e praticamente, por exemplo, matriz do tipo inteiro de 16 bits, mas alocaria mais memória do que realmente precisa para armazenar essa matriz. Para evitar isso, você pode ativar a
dtype
opçãoread_csv
. Você não deseja armazenar os itens da matriz como um número inteiro longo onde, na verdade, você pode ajustá-los com um número inteiro de 8 bits (np.int8
ounp.uint8
).Observe o seguinte mapa de tipo.
Fonte: https://pbpython.com/pandas_dtypes.html
Você pode passar o
dtype
parâmetro como um parâmetro nos métodos de pandas como ditadoread
como {column: type}.Opção 2: Leia por Chunks
A leitura dos dados em partes permite acessar uma parte dos dados na memória e você pode aplicar o pré-processamento aos dados e preservar os dados processados em vez dos dados brutos. Seria muito melhor se você combinar essa opção com o primeiro, dtypes .
Quero destacar as seções do livro de receitas dos pandas para esse processo, onde você pode encontrá-lo aqui . Observe essas duas seções lá;
Opção 3: Dask
O Dask é uma estrutura definida no site da Dask como:
Nasceu para cobrir as partes necessárias onde os pandas não podem alcançar. O Dask é uma estrutura poderosa que permite muito mais acesso a dados, processando-o de maneira distribuída.
Você pode usar o dask para pré-processar seus dados como um todo. O Dask cuida da parte do chunking. Assim, ao contrário dos pandas, você pode apenas definir suas etapas de processamento e deixar o Dask fazer o trabalho. O Dask não aplica os cálculos antes de ser explicitamente enviado por
compute
e / oupersist
(veja a resposta aqui para a diferença).Outras ajudas (ideias)
fonte
Além das respostas acima, para quem deseja processar CSV e depois exportar para csv, parquet ou SQL, o d6tstack é outra boa opção. Você pode carregar vários arquivos e ele lida com alterações no esquema de dados (colunas adicionadas / removidas). O suporte fragmentado do núcleo já está incorporado.
fonte
Caso alguém ainda esteja procurando algo assim, descobri que essa nova biblioteca chamada modin pode ajudar. Ele usa computação distribuída que pode ajudar na leitura. Aqui está um bom artigo comparando sua funcionalidade com os pandas. Essencialmente, ele usa as mesmas funções que os pandas.
fonte
modin
compara ao bem estabelecidodask.dataframe
? Por exemplo, consulte mover de pandas para dask para utilizar todos os núcleos de CPU locais .Antes de usar a opção chunksize, se você quiser ter certeza sobre a função do processo que deseja escrever dentro do loop for de chunking, conforme mencionado por @unutbu, basta usar a opção nrows.
Depois de ter certeza de que o bloco do processo está pronto, você pode colocá-lo no loop chunking for para todo o quadro de dados.
fonte