No momento, estou tentando abrir um arquivo com pandas e python para fins de aprendizado de máquina. Seria ideal para todos eles em um DataFrame. Agora, o arquivo tem 18 GB de largura e minha RAM tem 32 GB, mas continuo recebendo erros de memória.
De sua experiência é possível? Se você não conhece uma maneira melhor de contornar isso? (tabela do hive? aumenta o tamanho da minha RAM para 64? cria um banco de dados e acessa-o a partir de python)
pandas
é que você precisa ter de 5 a 10 vezes mais memória RAM. Eu recomendo fazerinplace
operações, chamar explicitamentegarbage.collector
para desalocar objetos.Respostas:
Se for um arquivo csv e você não precisar acessar todos os dados de uma vez ao treinar seu algoritmo, poderá lê-lo em pedaços. O
pandas.read_csv
método permite que você leia um arquivo em pedaços como este:Aqui está a documentação do método
fonte
Existem duas possibilidades: você precisa ter todos os dados na memória para processamento (por exemplo, o algoritmo de aprendizado de máquina gostaria de consumir todos de uma vez) ou pode ficar sem eles (por exemplo, o algoritmo precisa apenas de amostras de linhas ou colunas de uma só vez).
No primeiro caso, você precisará resolver um problema de memória . Aumente o tamanho da sua memória, alugue uma máquina na nuvem com muita memória, use operações no local, forneça informações sobre o tipo de dados em que você está lendo, exclua todas as variáveis não utilizadas e colete lixo, etc.
É muito provável que 32 GB de RAM não sejam suficientes para o Pandas manipular seus dados. Observe que o número inteiro "1" tem apenas um byte quando armazenado como texto, mas 8 bytes quando representado como
int64
(que é o padrão quando o Pandas lê o texto). Você pode fazer o mesmo exemplo com um número de ponto flutuante "1.0" que se expande de uma sequência de 3 bytes para uma de 8 bytesfloat64
por padrão. Você pode ganhar algum espaço informando ao Pandas com precisão quais tipos usar para cada coluna e forçando as menores representações possíveis, mas nem começamos a falar da sobrecarga da estrutura de dados do Python aqui, o que pode adicionar um ponteiro extra ou dois aqui ou ali facilmente e os ponteiros têm 8 bytes cada, em uma máquina de 64 bits.Resumindo: não, 32 GB de RAM provavelmente não são suficientes para o Pandas manipular um arquivo de 20 GB.
No segundo caso (que é mais realista e provavelmente se aplica a você), você precisa resolver um problema de gerenciamento de dados . De fato, ter que carregar todos os dados quando você realmente precisa apenas de partes deles para processamento, pode ser um sinal de mau gerenciamento de dados. Existem várias opções aqui:
Use um banco de dados SQL. Se você puder, é quase sempre a primeira escolha e uma solução decentemente confortável. 20 GB parece o tamanho que a maioria dos bancos de dados SQL suportaria bem, sem a necessidade de distribuição, mesmo em um laptop (de ponta). Você poderá indexar colunas, fazer agregações básicas via SQL e obter as subamostras necessárias no Pandas para um processamento mais complexo usando um simples
pd.read_sql
. Mover os dados para um banco de dados também fornecerá a você a oportunidade de pensar nos tipos e tamanhos de dados reais de suas colunas.Se seus dados forem principalmente numéricos (ou seja, matrizes ou tensores), considere mantê-los em um formato HDF5 (consulte PyTables ), que permite ler convenientemente apenas as fatias necessárias de enormes matrizes do disco. O básico numpy.save e numpy.load também obtêm o mesmo efeito através do mapeamento de memória das matrizes no disco. Para GIS e dados de varredura relacionados, existem bancos de dados dedicados , que podem não se conectar aos pandas tão diretamente quanto o SQL, mas também devem permitir fatias e consultas de forma conveniente.
O Pandas não suporta esse mapeamento de memória "parcial" de HDF5 ou matrizes numpy, tanto quanto eu sei. Se você ainda deseja um tipo de solução para "pandas-puros", pode tentar contornar o "sharding": armazenando as colunas da sua enorme mesa separadamente (por exemplo, em arquivos separados ou em "tabelas" separadas de um único HDF5) arquivo) e apenas carregando os necessários sob demanda ou armazenando os blocos de linhas separadamente. No entanto, você precisará implementar a lógica para carregar os trechos necessários, reinventando as bicicletas já implementadas na maioria dos bancos de dados SQL; portanto, talvez a opção 1 ainda seja mais fácil aqui. Se seus dados vierem em um CSV, você poderá processá-los em partes, especificando o
chunksize
parâmetro parapd.read_csv
.fonte
Acabei de ter esse problema há alguns dias! Não tenho certeza se isso ajuda no seu caso específico, pois você não está fornecendo tantos detalhes, mas minha situação era trabalhar offline em um conjunto de dados 'grande'. Os dados foram obtidos como arquivos CSV compactados em gb de 20 GB a partir de medidores de energia, dados de séries temporais em intervalos de alguns segundos.
Arquivo E / S:
Crie um iterador de bloco diretamente sobre o arquivo gzip (não descompacte!)
Iterar sobre os pedaços
Dentro do loop do bloco, estou fazendo algumas filtragem e re-amostragem no prazo. Com isso, reduzi o tamanho de 20 GB para algumas centenas de MB HDF5 para mais exploração de dados offline.
fonte
Na minha experiência, a inicialização
read_csv()
com o parâmetrolow_memory=False
tende a ajudar na leitura de arquivos grandes. Não acho que você tenha mencionado o tipo de arquivo que está lendo, portanto, não tenho certeza de como isso se aplica à sua situação.fonte
Se o seu arquivo é um CSV, você pode simplesmente fazê-lo no Chunk by Chunk. Você pode simplesmente fazer:
fonte