Biblioteca Polars para Rust: Guia Completo
Polars é uma biblioteca de alto desempenho para manipulação de dados no formato DataFrame, escrita em Rust. Ela oferece uma API familiar para usuários de pandas, mas supera significativamente a biblioteca Python em velocidade e eficiência de memória. Diferente do pandas, que muitas vezes esbarra em limitações de execução single-thread e consumo de RAM, o Polars foi projetado desde o início para operar em modo multithread e utiliza lazy evaluation (API Lazy) para otimizar consultas.
O principal objetivo do Polars é fornecer uma ferramenta para processar grandes volumes de dados (de centenas de megabytes a vários terabytes) em um único nó, sem precisar de sistemas distribuídos como Spark. Isso é alcançado através de gerenciamento eficiente de memória (zero-copy, uso do Apache Arrow como backend), vetorização de operações e paralelização automática. Para desenvolvedores Rust, o Polars não é apenas um wrapper de uma biblioteca Python, mas sim uma biblioteca nativa que aproveita ao máximo os recursos da linguagem: segurança de memória, sistema de tipos e performance.
A biblioteca oferece duas APIs: Eager (execução imediata) e Lazy (execução preguiçosa). A API Eager é ideal para trabalho interativo e datasets pequenos, quando você precisa ver o resultado imediatamente. A API Lazy permite construir um plano de consulta que é otimizado e executado em uma única passada, algo crucial para transformações complexas e grandes volumes de dados. O Polars também suporta leitura e escrita de CSV, Parquet, JSON, IPC (Arrow) e bancos de dados via SQL.
Instalação
Para adicionar o Polars a um projeto Rust, adicione a dependência no arquivo Cargo.toml:
[dependencies]
polars = "0.44.0" # Verifique a versão mais recente no crates.io
Se você precisar de funcionalidades extras (como suporte a expressões regulares em strings, trabalho com datas ou integração com SQL), use as features:
[dependencies]
polars = { version = "0.44.0", features = ["lazy", "strings", "dtype-date", "dtype-datetime", "sql", "parquet", "csv"] }
Principais features:
lazy— API Lazy (essencial para trabalho sério)strings— métodos para manipulação de strings (contains, replace, extract)dtype-date,dtype-datetime— suporte a tipos de datasql— interface SQLparquet— leitura/escrita de Parquetcsv— leitura/escrita de CSVis_in,rank,moment— métodos adicionais
Após adicionar a dependência, execute:
cargo build
Primeiros Passos
Um exemplo mínimo de criação de DataFrame e execução de uma consulta simples:
use polars::prelude::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Criando um DataFrame a partir de vetores
let df = df! [
"nome" => &["Alice", "Bob", "Carlos"],
"idade" => &[25, 30, 35],
"salario" => &[50000, 60000, 70000]
]?;
println!("DataFrame original:\n{:?}", df);
// Filtragem: quem tem mais de 28 anos
let filtrado = df.clone().lazy()
.filter(col("idade").gt(lit(28)))
.collect()?;
println!("Filtrado (idade > 28):\n{:?}", filtrado);
// Agregação: salário médio
let salario_medio = df.clone().lazy()
.select([col("salario").mean().alias("salario_medio")])
.collect()?;
println!("Salário médio:\n{:?}", salario_medio);
Ok(())
}
Este código cria uma tabela com três colunas, filtra as linhas por idade e calcula o salário médio. Observe o uso de lazy() — mesmo para operações simples, é recomendado para aproveitar a otimização de consultas.