Este guia foi desenhado para quem já tem familiaridade com SQL e deseja migrar para o Polars, aproveitando a máxima performance do hardware moderno.
O Polars não é apenas uma "alternativa ao Pandas"; ele é, essencialmente, um motor de consulta (Query Engine) OLAP escrito em Rust que utiliza a sintaxe Python para expressar planos de execução lógica.
1. Preparação do Ambiente com uv
Para garantir que você está usando a versão mais recente e otimizada para o seu chip (especialmente se for Apple Silicon), utilize o uv para gerenciar o projeto.
# Inicie um novo projeto
uv init lab-polars
cd lab-polars
# Adicione o Polars e suporte a arquivos Parquet
uv add polars pyarrow
2. O Modelo Mental: Expressões e Contextos
Diferente do SQL, onde você escreve uma string única, no Polars você compõe Expressões dentro de Contextos.
-
Contextos: Definem "onde" você está operando (
select,filter,with_columns,group_by). -
Expressões: Definem "o que" você está fazendo com as colunas (
pl.col("vendas").sum()).
Dica: No Polars, quase tudo é vetorizado. Se você estiver pensando em usar um loop
for, provavelmente há uma forma mais rápida de fazer isso usando expressões.
3. Pedra de Roseta: SQL vs. Polars
Abaixo, as operações mais comuns traduzidas diretamente da linguagem SQL para a sintaxe Polars.
3.1 Seleção e Filtro (SELECT & WHERE)
| Operação SQL | Sintaxe Polars |
|---|---|
SELECT nome, idade FROM tabela |
df.select("nome", "idade") |
SELECT * FROM tabela WHERE idade > 25 |
df.filter(pl.col("idade") > 25) |
SELECT DISTINCT categoria FROM tabela |
df.select("categoria").unique() |
3.2 Agregações (GROUP BY)
O Polars brilha aqui devido ao seu motor multithreaded que processa grupos em paralelo.
| Operação SQL | Sintaxe Polars |
|---|---|
GROUP BY regiao |
df.group_by("regiao") |
COUNT(*), AVG(vendas) |
.agg([pl.len(), pl.col("vendas").mean()]) |
HAVING total > 1000 |
.filter(pl.col("total") > 1000) |
3.3 Window Functions (O Poder do .over())
Se você usa OVER (PARTITION BY ...) no SQL, a transição para Polars é natural e extremamente poderosa.
SQL:
SELECT
vendedor,
venda,
venda / SUM(venda) OVER (PARTITION BY regiao) as share_regiao
FROM vendas
Polars:
df.with_columns(
(pl.col("venda") / pl.col("venda").sum().over("regiao")).alias("share_regiao")
)
4. Otimização Automática: A Lazy API
Em SQL, o banco de dados não executa sua query linha por linha; ele cria um plano e otimiza (Predicate Pushdown). O Polars faz exatamente o mesmo através da sua Lazy API.
Como usar o Modo Lazy:
- Use
scan_parquetouscan_csvem vez deread_. - Construa toda a sua lógica de transformação.
- Chame
.collect()no final para disparar a execução.
import polars as pl
# Criando um plano lógico (não carrega os dados ainda)
lazy_plan = (
pl.scan_parquet("dados_gigantes.parquet")
.filter(pl.col("status") == "ERRO")
.group_by("servidor")
.agg(pl.len().alias("total_erros"))
)
# Agora sim, o processamento ocorre (usando todos os núcleos da CPU)
df_final = lazy_plan.collect()
5. Exemplo Real: O Showdown de Logs Massivos
Para o seu post no dev.to, aqui está um exemplo prático que ilustra a diferença brutal de performance entre a abordagem legada (Pandas) e a moderna (Polars).
Cenário: Processar um arquivo de log de 10GB (aprox. 100 milhões de linhas) para encontrar a média de tempo de resposta por endpoint apenas para status 200.
Abordagem Pandas (O Gargalo)
import pandas as pd
import time
start = time.time()
# Pandas carrega tudo na RAM (Pode causar erro de memória)
df = pd.read_csv("access_logs.csv")
df_filtered = df[df['status'] == 200]
result = df_filtered.groupby('endpoint')['response_time'].mean()
print(f"Pandas levou: {time.time() - start:.2f} segundos")
Abordagem Polars (A Eficiência)
import polars as pl
import time
start = time.time()
# Polars usa Lazy API e Streaming para processar sem estourar a RAM
result = (
pl.scan_csv("access_logs.csv")
.filter(pl.col("status") == 200)
.group_by("endpoint")
.agg(pl.col("response_time").mean())
.collect(streaming=True)
)
print(f"Polars levou: {time.time() - start:.2f} segundos")
Resultado Típico: Em hardware Apple Silicon, o Polars costuma ser 10x a 50x mais rápido que o Pandas para esta tarefa, consumindo apenas uma fração da memória RAM devido ao processamento por chunks.
Conclusão
Ao adotar o Polars, você deixa de ser um "manipulador de tabelas" para se tornar um "arquiteto de dados". O Python serve como a interface amigável, enquanto o motor em Rust garante que seu MacBook não se torne um aquecedor de mãos ineficiente.
Top comments (0)