Polars em Python: A Alternativa Rápida ao Pandas — 2026 | Python Brasil

Conheça o Polars, a biblioteca Python escrita em Rust para DataFrames ultrarrápidos. Comparação com Pandas, benchmarks, exemplos práticos e guia de migração.

6 min de leitura Equipe python.dev.br

Se você trabalha com dados em Python, provavelmente já usa o Pandas no dia a dia. Ele é a biblioteca padrão para manipulação de DataFrames há mais de uma década. Mas nos últimos anos, uma alternativa vem ganhando espaço rapidamente: o Polars — uma biblioteca de DataFrames escrita em Rust, projetada para ser extremamente rápida e eficiente em memória.

Neste artigo, vamos explorar o que torna o Polars especial, comparar com o Pandas em benchmarks reais, e mostrar como começar a usá-lo nos seus projetos.

O Que É o Polars

Polars é uma biblioteca open-source para manipulação de dados tabulares em Python (e também em Rust e Node.js). Diferente do Pandas, que é implementado em Python/C, o Polars foi escrito do zero em Rust — a mesma linguagem por trás de ferramentas modernas como Ruff e uv.

As características principais do Polars incluem:

  • Execução paralela automática — utiliza todos os núcleos do processador sem configuração extra
  • Avaliação lazy (preguiçosa) — otimiza queries antes de executá-las
  • Consumo de memória eficiente — usa Apache Arrow como formato interno
  • API expressiva — baseada em expressões encadeáveis e composíveis
  • Sem dependência do NumPy — funciona de forma independente

Instalação

Para instalar o Polars, o ideal é usar um ambiente virtual dedicado. Com uv:

# Terminal
uv pip install polars

# Ou com pip tradicional
pip install polars

Para funcionalidades extras como leitura de Excel e conexão com bancos de dados:

pip install 'polars[all]'

Polars vs Pandas: Benchmark de Performance

Vamos comparar as duas bibliotecas em uma operação comum — ler um CSV, filtrar linhas e agrupar dados:

import time
import pandas as pd
import polars as pl

# Gerando dados de exemplo (1 milhão de linhas)
import numpy as np
np.random.seed(42)
n = 1_000_000

dados = {
    "cidade": np.random.choice(["São Paulo", "Rio", "Curitiba", "BH", "Salvador"], n),
    "categoria": np.random.choice(["A", "B", "C"], n),
    "valor": np.random.uniform(10, 1000, n),
    "quantidade": np.random.randint(1, 100, n),
}

# --- Pandas ---
inicio = time.perf_counter()
df_pd = pd.DataFrame(dados)
resultado_pd = (
    df_pd[df_pd["valor"] > 100]
    .groupby(["cidade", "categoria"])
    .agg({"valor": "mean", "quantidade": "sum"})
)
tempo_pandas = time.perf_counter() - inicio

# --- Polars ---
inicio = time.perf_counter()
df_pl = pl.DataFrame(dados)
resultado_pl = (
    df_pl.filter(pl.col("valor") > 100)
    .group_by(["cidade", "categoria"])
    .agg(
        pl.col("valor").mean(),
        pl.col("quantidade").sum(),
    )
)
tempo_polars = time.perf_counter() - inicio

print(f"Pandas: {tempo_pandas:.3f}s")
print(f"Polars: {tempo_polars:.3f}s")
print(f"Polars foi {tempo_pandas / tempo_polars:.1f}x mais rápido")

Em testes típicos com 1 milhão de linhas, o Polars costuma ser 3x a 10x mais rápido que o Pandas nesse tipo de operação. A diferença aumenta conforme o dataset cresce, especialmente por causa do paralelismo automático.

Lazy vs Eager: O Poder da Avaliação Preguiçosa

Uma das maiores vantagens do Polars é o modo lazy. Em vez de executar cada operação imediatamente (modo eager, como o Pandas faz), o Polars constrói um plano de execução e otimiza tudo antes de rodar:

import polars as pl

# Modo lazy — nada é executado ainda
query = (
    pl.scan_csv("vendas.csv")  # scan_ em vez de read_
    .filter(pl.col("status") == "concluída")
    .filter(pl.col("valor") > 50)
    .group_by("produto")
    .agg(
        pl.col("valor").sum().alias("total_vendas"),
        pl.col("valor").count().alias("num_vendas"),
    )
    .sort("total_vendas", descending=True)
    .head(10)
)

# Agora sim, executa com otimizações
resultado = query.collect()
print(resultado)

O otimizador do Polars pode, por exemplo, combinar os dois filter em um só, aplicar projeção de colunas (ler apenas as colunas necessárias do CSV) e reordenar operações para minimizar o uso de memória. Isso faz uma diferença enorme com arquivos grandes.

API de Expressões: A Filosofia do Polars

O Polars usa um sistema de expressões que é diferente do Pandas. Em vez de acessar colunas como atributos ou usar .apply(), você compõe expressões com pl.col():

import polars as pl

df = pl.DataFrame({
    "nome": ["Ana", "Bruno", "Carla", "Diego", "Eva"],
    "idade": [28, 35, 42, 31, 26],
    "salario": [5500, 8200, 12000, 7100, 4800],
    "departamento": ["TI", "TI", "Gestão", "TI", "Gestão"],
})

# Expressões encadeáveis e composíveis
resultado = df.select(
    pl.col("nome"),
    pl.col("salario").alias("salario_atual"),
    (pl.col("salario") * 1.10).round(2).alias("salario_reajustado"),
    pl.col("idade").mean().over("departamento").alias("idade_media_dept"),
    pl.when(pl.col("salario") > 7000)
    .then(pl.lit("Sênior"))
    .otherwise(pl.lit("Pleno"))
    .alias("nivel"),
)

print(resultado)

Esse estilo baseado em expressões é mais declarativo e permite que o Polars otimize internamente cada operação. Se você já programa com boas práticas Python, vai perceber que o código fica limpo e legível.

Leitura de Diferentes Formatos

O Polars suporta vários formatos de arquivo nativamente:

import polars as pl

# CSV
df = pl.read_csv("dados.csv")

# Parquet (formato colunar, ideal para big data)
df = pl.read_parquet("dados.parquet")

# JSON
df = pl.read_json("dados.json")

# Lazy scan — não carrega tudo na memória
lazy_df = pl.scan_parquet("dados_grandes.parquet")

# Escrita
df.write_parquet("saida.parquet")
df.write_csv("saida.csv")

O formato Parquet merece destaque especial. Como é colunar e comprimido, o Polars consegue ler apenas as colunas necessárias no modo lazy, economizando memória e tempo de I/O.

Joins e Operações Comuns

Operações de join são frequentes em ciência de dados. Veja como funcionam no Polars:

import polars as pl

clientes = pl.DataFrame({
    "id_cliente": [1, 2, 3, 4],
    "nome": ["Ana", "Bruno", "Carla", "Diego"],
    "cidade": ["SP", "RJ", "SP", "BH"],
})

pedidos = pl.DataFrame({
    "id_pedido": [101, 102, 103, 104, 105],
    "id_cliente": [1, 2, 1, 3, 2],
    "valor": [150.0, 200.0, 75.0, 320.0, 180.0],
})

# Join
resultado = clientes.join(pedidos, on="id_cliente", how="left")

# Agregação após join
resumo = (
    resultado
    .group_by("nome", "cidade")
    .agg(
        pl.col("valor").sum().alias("total_gasto"),
        pl.col("id_pedido").count().alias("num_pedidos"),
    )
    .sort("total_gasto", descending=True)
)

print(resumo)

Quando Usar Polars vs Pandas

Nem sempre o Polars é a melhor escolha. Aqui vai um guia prático:

Use Polars quando:

  • Seu dataset tem mais de 100 mil linhas
  • Você precisa de performance máxima
  • Trabalha com arquivos Parquet
  • Quer aproveitar paralelismo automático
  • Está construindo pipelines de dados

Mantenha o Pandas quando:

  • Seu dataset é pequeno (menos de 50 mil linhas)
  • Precisa de integração com bibliotecas que exigem Pandas (scikit-learn, Matplotlib)
  • Sua equipe já domina a API do Pandas
  • Usa funcionalidades específicas do Pandas sem equivalente no Polars

A boa notícia é que os dois podem coexistir. O Polars oferece conversão fácil:

# Polars para Pandas
df_pandas = df_polars.to_pandas()

# Pandas para Polars
df_polars = pl.from_pandas(df_pandas)

Migrando do Pandas para o Polars

Se você já tem código em Pandas e quer migrar gradualmente, aqui estão as equivalências mais comuns:

PandasPolars
df["coluna"]df.select("coluna") ou df["coluna"]
df[df["x"] > 10]df.filter(pl.col("x") > 10)
df.groupby("x").agg({"y": "sum"})df.group_by("x").agg(pl.col("y").sum())
df.merge(df2, on="id")df.join(df2, on="id")
df.apply(func)df.select(pl.col("x").map_elements(func))
df.sort_values("x")df.sort("x")

A dica é migrar aos poucos: comece usando Polars para leitura e processamento pesado, converta para Pandas quando precisar de compatibilidade com outras bibliotecas.

Conclusão

O Polars representa uma nova geração de ferramentas para dados em Python — mais rápido, mais eficiente e com uma API moderna. Se você trabalha com tipagem estática e boas práticas, vai apreciar a filosofia do Polars de ser explícito e composível.

Para quem está começando a explorar o ecossistema de IA e dados, vale também conferir como usar APIs de LLMs em Python — outra tendência forte do ecossistema Python em 2026.

O Polars não veio para substituir o Pandas, mas para complementá-lo. Experimente no seu próximo projeto de dados e veja a diferença de performance na prática.

Por que Rust? O Polars é escrito em Rust, a mesma linguagem por trás de ferramentas como Ruff e uv. Rust oferece performance próxima ao C com garantias de segurança de memória em tempo de compilação — o que explica a velocidade impressionante do Polars sem sacrificar a estabilidade.

E

Equipe python.dev.br

Contribuidor do Python Brasil — Aprenda Python em Português