🇧🇷Um Bilhão de Linhas: Desafio de Processamento de Dados com Python

Introdução

O objetivo deste projeto é demonstrar como processar eficientemente um arquivo de dados massivo contendo 1 bilhão de linhas (~14GB), especificamente para calcular estatísticas (Incluindo agregação e ordenação que são operações pesadas) utilizando Python.

Este desafio foi inspirado no The One Billion Row Challenge, originalmente proposto para Java.

O arquivo de dados consiste em medições de temperatura de várias estações meteorológicas. Cada registro segue o formato <string: nome da estação>;<double: medição>, com a temperatura sendo apresentada com precisão de uma casa decimal.

Aqui estão dez linhas de exemplo do arquivo:

Hamburg;12.0
Bulawayo;8.9
Palembang;38.8
St. Johns;15.2
Cracow;12.6
Bridgetown;26.9
Istanbul;6.2
Roseau;34.4
Conakry;31.2
Istanbul;23.0

O desafio é desenvolver um programa Python capaz de ler esse arquivo e calcular a temperatura mínima, média (arredondada para uma casa decimal) e máxima para cada estação, exibindo os resultados em uma tabela ordenada por nome da estação.

stationmin_temperaturemean_temperaturemax_temperature
Abha-31.118.066.5
Abidjan-25.926.074.6
Abéché-19.829.479.9
Accra-24.826.476.3
Addis Ababa-31.816.063.9
Adelaide-31.817.371.5
Aden-19.629.178.3
Ahvaz-24.025.472.6
Albuquerque-35.014.061.9
Alexandra-40.111.067.9
Yangon-23.627.577.3
Yaoundé-26.223.873.4
Yellowknife-53.4-4.346.7
Yerevan-38.612.462.8
Yinchuan-45.29.056.9
Zagreb-39.210.758.1
Zanzibar City-26.526.075.2
Zürich-42.09.363.6
Ürümqi-42.17.456.7
İzmir-34.417.967.9

Dependências

Para executar os scripts deste projeto, você precisará das seguintes bibliotecas:

  • Polars: 0.20.3
  • DuckDB: 0.10.0
  • Dask[complete]: ^2024.2.0

Resultados

Os testes foram realizados em um laptop equipado com um processador M1 da Apple e 8GB de RAM. As implementações utilizaram abordagens puramente Python, Pandas, Dask, Polars e DuckDB. Os resultados de tempo de execução para processar o arquivo de 1 bilhão de linhas são apresentados abaixo:

ImplementaçãoTempo
Bash + awk25 minutos
Python20 minutos
Python + Pandas263 sec
Python + Dask155.62 sec
Python + Polars33.86 sec
Python + Duckdb14.98 sec

Conclusão

Este desafio destacou claramente a eficácia de diversas bibliotecas Python na manipulação de grandes volumes de dados. Métodos tradicionais como Bash (25 minutos), Python puro (20 minutos) e até mesmo o Pandas (5 minutos) demandaram uma série de táticas para implementar o processamento em “lotes”, enquanto bibliotecas como Dask, Polars e DuckDB provaram ser excepcionalmente eficazes, requerendo menos linhas de código devido à sua capacidade inerente de distribuir os dados em “lotes em streaming” de maneira mais eficiente. O DuckDB se sobressaiu, alcançando o menor tempo de execução graças à sua estratégia de execução e processamento de dados.

Esses resultados enfatizam a importância de selecionar a ferramenta adequada para análise de dados em larga escala, demonstrando que Python, com as bibliotecas certas, é uma escolha poderosa para enfrentar desafios de big data.

Duckdb vence tambem com 1 milhao de linhas, realmente é o melhor

Como Executar

Para executar este projeto e reproduzir os resultados:

  1. Clone esse repositório
  2. Definir a versao do Python usando o pyenv local 3.12.1
  3. poetry env use 3.12.1poetry install --no-root e poetry lock --no-update
  4. Execute o comando python src/create_measurements.py para gerar o arquivo de teste
  5. Tenha paciência e vá fazer um café, vai demorar uns 10 minutos para gerar o arquivo
  6. Certifique-se de instalar as versões especificadas das bibliotecas Dask, Polars e DuckDB
  7. Execute os scripts python src/using_python.pypython src/using_pandas.pypython src/using_dask.pypython src/using_polars.py e python src/using_duckdb.py através de um terminal ou ambiente de desenvolvimento que suporte Python.

Este projeto destaca a versatilidade do ecossistema Python para tarefas de processamento de dados, oferecendo valiosas lições sobre escolha de ferramentas para análises em grande escala.

Bonus

Para rodar o script Bash descrito, você precisa seguir alguns passos simples. Primeiro, assegure-se de que você tenha um ambiente Unix-like, como Linux ou macOS, que suporta scripts Bash nativamente. Além disso, verifique se as ferramentas utilizadas no script (wcheadpvawk, e sort) estão instaladas em seu sistema. A maioria dessas ferramentas vem pré-instalada em sistemas Unix-like, mas pv (Pipe Viewer) pode precisar ser instalado manualmente.

Instalando o Pipe Viewer (pv)

Se você não tem o pv instalado, pode facilmente instalá-lo usando o gerenciador de pacotes do seu sistema. Por exemplo:

  • No Ubuntu/Debian:sudo apt-get update sudo apt-get install pv
  • No macOS (usando Homebrew):brew install pv

Preparando o Script

  1. Dê permissão de execução para o arquivo script. Abra um terminal e execute:chmod +x process_measurements.sh
  2. Rode o script. Abra um terminal e execute:./src/using_bash_and_awk.sh 1000

Neste exemplo, apenas as primeiras 1000 linhas serão processadas.

Ao executar o script, você verá a barra de progresso (se pv estiver instalado corretamente) e, eventualmente, a saída esperada no terminal ou em um arquivo de saída, se você decidir modificar o script para direcionar a saída.

repository: https://github.com/GustavoSantanaData/One-Billion-Row-Challenge-Python/tree/main