Alura > Cursos de Data Science > Cursos de > Conteúdos de > Primeiras aulas do curso Polars: explorando polars com Rust

Polars: explorando polars com Rust

Unindo o Polars ao Rust - Apresentação

Olá! Meu nome é Allan Spadini, sou instrutor na Alura e vou te acompanhar nesta jornada

Audiodescrição: Allan se descreve um homem branco, com cabelos castanhos e lisos e sobrancelhas grossas. Veste uma camiseta preta lisa e, à sua frente, possui um microfone na altura do pescoço. Ele está no estúdio da Alura, com iluminação azul e uma estante ao com objetos decorativos.

Neste curso, vamos trabalhar com a biblioteca Polars, utilizando a linguagem Rust. A ideia é que possamos compilar o código gerado com a linguagem Rust de forma fácil e gerar um executável.

Vamos trabalhar com um dataset de uma plataforma de streaming de animes, um dataset grande, no qual queremos utilizar o executável gerado pela Rust para processar esses dados rapidamente.

Para acompanhar este curso, nós disponibilizaremos uma lista de exercícios na qual será possível realizar outras atividades e trabalhar com diferentes tipos de dataset, aplicando as atividades aprendidas no curso. Nesta lista de exercícios, será possível interagir com diversos arquivos, utilizando os links disponíveis, além de acessar o gabarito de cada uma das atividades propostas.

Para acompanhar o curso, é necessário ter concluído os outros cursos da formação de Polars. Não é necessário conhecer a linguagem Rust, pois a exploraremos juntos ao longo deste curso.

Nos vemos nos próximos vídeos!

Unindo o Polars ao Rust - Criando um DataFrame

Somos cientistas de dados e estamos trabalhando com dados de uma plataforma de streaming de animes, ou seja, estamos lidando com uma grande quantidade de dados, onde as pessoas interagem continuamente com essa plataforma. Por isso, precisamos do Polars para lidar com essa grande quantidade de dados, e desta vez utilizaremos a linguagem Rust, para que possamos utilizar o Polars e também compilar nosso código. Com o código compilado e convertido em código de máquina, ele rodará rapidamente, permitindo processar essa grande quantidade de dados de forma eficiente.

Configurando o projeto Rust

Para começar, precisamos criar o projeto em Rust. Se você já instalou o Rust conforme a atividade que deixamos preparada para configurar o ambiente, já deve ter o gerenciador de pacotes do Rust, que é o cargo. No VSCode, abrimos um terminal e executamos:

cargo new projeto_polars

Isso criará a aplicação, e aparecerá uma pasta chamada projeto_polars no lado esquerdo.

Definindo as dependências no arquivo Cargo.toml

Dentro dessa pasta, encontraremos outra pasta, a src, que conterá nossos arquivos, e o arquivo Cargo.toml. Ao clicar no Cargo.toml, veremos uma série de informações já criadas, como a versão do projeto, que é 0.1.0, e as dependências do projeto. Inicialmente, não há dependências exibidas, mas utilizaremos o Polars. Portanto, copiamos e colamos a dependência do Polars: polars = {version="0.46.0"}.

[package]
name = "projeto_polars"
version = "0.1.0"
edition = "2024"

[dependencies]
polars = {version="0.46.0"}

Além disso, nos projetos em Rust, não fazemos simplesmente como no Python, onde apenas importamos o Polars. Precisamos especificar quais funcionalidades do Polars queremos utilizar.

Já preparamos algumas features (funcionalidades), e passaremos esse arquivo pronto, contendo features específicas como describe, lazy, strings, regex, parquet e json. São várias funcionalidades que utilizaremos no projeto. Após isso, basta salvar o arquivo:

[package]
name = "projeto_polars"
version = "0.1.0"
edition = "2024"

[dependencies]
polars = {version="0.46.0",features=["describe","lazy","strings","regex","parquet","json"]}

Criando o arquivo principal do projeto

Podemos partir para o arquivo main.rs, que estará dentro da pasta src. O main.rs é um arquivo principal, onde já foi criado um "Hello, World!" caso nunca tenhamos trabalhado com Rust:

fn main() {
    println!("Hello, world!");
}

Se digitarmos, por exemplo, cargo run no terminal, ele deve compilar e executar o código imprimindo o "Hello, World!". No entanto, se não estivermos na pasta correta, ocorrerá um erro. Estávamos em uma pasta acima do projeto Polars. Precisamos entrar na pasta do projeto Polars, digitando:

cd projeto_polars

Agora, podemos tentar compilar o código novamente. Ao digitar cargo run, ele tentará rodar o código. Na primeira vez, o processo de compilação pode demorar um pouco.

Estruturando o primeiro dataframe com Polars

Vamos pensar nesta impressão voltada para os dados. Estamos tentando entender o problema dos animes e queremos começar a criar nossa primeira estrutura de dados que vai armazenar o nome dos animes e suas respectivas notas. Vamos criar essa estrutura.

Em main.rs, queremos criar um dataframe. Vamos criar um dataframe chamado df. Para isso, digitamos let df: DataFrame = df!():

fn main() {
    let df: DataFrame = df!();
    println!("Hello, world!");
}

Agora, dentro desse dataframe, queremos duas colunas: nome e score. Para criar a coluna nome, digitamos "nome" => ["Dragon Ball", "Naruto", "One Piece", "CDZ"]:

fn main() {
    let df: DataFrame = df!(
            "nome" => ["Dragon Ball", "Naruto", "One Piece", "CDZ"]
    );
    println!("Hello, world!");
}

Além disso, vamos criar a coluna score, que conterá uma nota respectiva para cada anime na plataforma. Copiamos a nota de cada anime e, assim, temos a estrutura básica do dataframe:

fn main() {
    let df: DataFrame = df!(
            "nome" => ["Dragon Ball", "Naruto", "One Piece", "CDZ"],
            "score" => [9.0, 9.5, 10.0, 10.0]
    );
    println!("Hello, world!");
}

Importando a biblioteca Polars e exibindo os dados

Precisamos extrair a informação do dataframe. Utilizamos o método .unwrap(); para extrair e colocar a informação dentro de df. Feito isso, podemos imprimir o dataframe para verificar se ele foi criado corretamente. Utilizamos println!("{:?}", df); para exibir o dataframe:

fn main() {
    let df: DataFrame = df!(
            "nome" => ["Dragon Ball", "Naruto", "One Piece", "CDZ"],
            "score" => [9.0, 9.5, 10.0, 10.0]
    ).unwrap();

    println!("{}", df);
}

Antes de rodar o comando cargo run, devemos fazer o import da biblioteca Polars com use polars::prelude::*:

use polars::prelude::*;

fn main() {
    let df: DataFrame = df!(
        {
            "nome" => ["Dragon Ball", "Naruto", "One Piece", "CDZ"],
            "score" => [9.0, 9.5, 10.0, 10.0]
        }
    ).unwrap();

    println!("{}", df);
}

Após realizar o import, compilamos o código e geramos o resultado. No terminal, verificamos que o dataframe foi criado com o nome dos animes em uma coluna e o score em outra.

nome

str

score

f64

Dragon Ball9.0
Naruto9.5
One Piece10.0
CDZ10.0

Considerações finais

Observamos que a função main pode ficar sobrecarregada se escrevermos todo o código do curso nela. No próximo vídeo, vamos mostrar como reescrever as informações em outra função, dentro de outro arquivo, e chamá-las na função main. Até o próximo vídeo!

Unindo o Polars ao Rust - Criando funções

Nós conseguimos criar nosso primeiro DataFrame, exibi-lo e imprimi-lo. No entanto, há um detalhe a considerar. Embora não seja exatamente um problema, criamos tudo o que precisávamos dentro da função main.rs. Talvez não seja a forma mais interessante ter todo o código e o processamento de grandes volumes de dados dentro da função main, pois isso pode torná-la muito carregada.

Visualizando o código inicial da função main

Para começar, vamos ver como o código estava inicialmente dentro da função main:

use polars::prelude::*;

fn main() {
    let df: DataFrame = df!(
        "name" => ["Dragon Ball", "Naruto", "One Piece", "CDZ"],
        "score" => [9.0, 9.5, 10.0, 10.0]
    )
    .unwrap();

    println!("{}", df)
}

Implementando a função imprimir_dataframe

Uma maneira de organizar melhor o código é criar outra função, externa à main, e colocá-la em outro arquivo. No canto esquerdo, ao clicar em "Explorer", podemos ver que temos apenas o arquivo main.rs. Podemos criar outro arquivo em Rust. Dentro da pasta src, clicamos para criar um novo arquivo, que chamaremos de anime_data.rs. Com isso, temos um novo arquivo.

Agora, queremos colocar o código que criamos dentro de uma função. Para isso, dentro de anime_data.rs, faremos o import de use polars::prelude::* para que possamos usar o Polars:

use polars::prelude::*;

Em seguida, criaremos a função. Para criar a função, basta digitar fn seguido do nome da função, que será imprimir_dataframe. Abrimos e fechamos parênteses, e também abrimos e fechamos chaves. Inicialmente, a função estará vazia:

fn imprimir_dataframe() {

}

Dentro dessas chaves, colocaremos o código que construímos no vídeo anterior. Com o código pronto, basta colá-lo dentro da função, e já teremos tudo organizado:

fn imprimir_dataframe(){
    // Criando o DataFrame dentro da função
    let df: DataFrame = df!(
        "name" => ["Dragon Ball", "Naruto", "One Piece", "CDZ"],
        "score" => [9.0, 9.5, 10.0, 10.0]
    )
    .unwrap();

    // Imprimindo o DataFrame
    println!("{}", df);
}

Tornando a função visível com pub

Para que a função criada possa ser utilizada, não basta apenas criá-la; é necessário publicá-la para que possamos chamá-la dentro do código da main. Para isso, precisamos digitar pub antes da definição da função:

pub fn imprimir_dataframe(){
    // Criando o DataFrame dentro da função
    let df: DataFrame = df!(
        "name" => ["Dragon Ball", "Naruto", "One Piece", "CDZ"],
        "score" => [9.0, 9.5, 10.0, 10.0]
    )
    .unwrap();

    // Imprimindo o DataFrame
    println!("{}", df);
}

Integrando a função imprimir_dataframe na main

Dentro da função main, devemos informar que temos o anime_data. Começamos removendo o polars.prelude, pois ele já está sendo chamado dentro do arquivo do anime_data, não precisamos dele aqui. Vamos adicionar mod anime_data;. Com isso, tudo estará correto. Já temos o mod anime_data, e agora basta chamar a função que criamos.

Vamos apagar o código criado no vídeo anterior e chamar a função de anime_data dentro do código. Para isso, digitamos anime_data::imprimir_dataframe();:

mod anime_data;

fn main() {
    anime_data::imprimir_dataframe();
}

Conclusão e próximos passos

Com isso, nosso código deve funcionar corretamente. No terminal, ao rodar o comando cargo run, o nosso DataFrame é impresso novamente.

nome

str

score

f64

Dragon Ball9.0
Naruto9.5
One Piece10.0
CDZ10.0

Agora, sabemos como criar nosso primeiro DataFrame, compilar o código e também como organizar o código em outro arquivo para que a função main fique mais clara.

Neste exemplo, trabalhamos com estruturas de dados relacionadas ao nosso projeto, mas o objetivo é carregar os dados da plataforma de Animes. Isso será abordado no próximo vídeo, onde trabalharemos com os dados salvos em uma pasta do projeto.

Até o próximo vídeo!

Sobre o curso Polars: explorando polars com Rust

O curso Polars: explorando polars com Rust possui 123 minutos de vídeos, em um total de 51 atividades. Gostou? Conheça nossos outros cursos de em Data Science, ou leia nossos artigos de Data Science.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas