Cover do episódio 52: Pandas e a ilusão de que manipular dado em memória é simples
#05229 de outubro, 20183 min leituraCódigo na PráticaS3 · 2018–2019

Pandas e a ilusão de que manipular dado em memória é simples

Pandas funcionava perfeitamente com os dados de teste. Quando rodei com o dataset real, recebi MemoryError. A lição: nunca assuma que o dado cabe.

PandasPythonDadosPerformance

MemoryError.

Sem traceback detalhado. Sem sugestão de fix. O processo simplesmente morreu porque tentei carregar 4GB de CSV em memória em máquina com 8GB de RAM — sendo que o sistema operacional e o Python já estavam usando metade.

Tinha funcionado perfeitamente com o arquivo de teste de 50MB.


Pandas é uma das bibliotecas mais poderosas para manipulação de dados em Python. A API é expressiva, a integração com NumPy é transparente, o ecossistema em volta é enorme. Para dataset que cabe em memória, é difícil bater.

O problema é exatamente esse: "que cabe em memória."

Em pesquisa, os primeiros datasets que você trabalha são pequenos — amostras, exemplos do professor, subconjuntos para testar a análise. Pandas funciona perfeitamente. Você aprende a API, fica confortável com o paradigma, passa a depender da ferramenta.

Depois alguém te dá o dataset real.


O que MemoryError ensinou:

Código que funciona em amostra não funciona em escala. A diferença entre amostra e dado real não é só tamanho — é distribuição, valores nulos, encoding inesperado, linhas malformadas. Amostra limpa não representa dado sujo.

Leitura em chunks existe por razão. Pandas tem read_csv(chunksize=N). Não é feature obscura — é o caminho para quando dado não cabe. Aprendi a existência depois do MemoryError, não antes.

Tipo de dado importa para memória. DataFrame com coluna de string que poderia ser category ocupa 10x mais. DataFrame com float64 que poderia ser float32 ocupa o dobro. Escolha de dtype não é só performance — é viabilidade.

Streaming é design, não otimização. Para dado que cresce, a arquitetura certa não carrega tudo em memória nunca. Essa intuição voltou quando comecei a trabalhar com pipelines de dados em plataforma.


A resolução prática naquele dia foi dividir o arquivo em partes, processar cada parte, agregar resultado. Funcionou. Mas foi uma solução de emergência, não de design.

A solução de design teria sido não assumir que o dado cabia desde o início. Teria sido perguntar "qual é o tamanho máximo que isso pode ter?" antes de escrever a primeira linha de código.

Essa pergunta — "e se o dado for maior?" — ficou. Hoje quando vejo código que carrega coleção inteira em memória antes de processar, sei exatamente qual é a próxima conversa que vamos ter.

Toda otimização de memória começa com a pergunta que deveria ter sido feita antes: qual é o volume máximo realista?

Essa semana: tem algum lugar no seu código que assume que dado cabe em memória? O que acontece se crescer 10x?