image

Acesse bootcamps ilimitados e +650 cursos

50
%OFF
Article image

CM

Caio Meorin03/07/2023 22:11
Compartilhe

Polars e a desmistificação do ensino de Data Science com Pandas

    Introdução

    Sabe-se que, quanto a organização e representação gráfica de dados de forma tabular, Pandas se destaca, sendo a API mais popular, em conjunto com Python. Entretanto, tamanha popularidade talvez provoque a famosa visão em túnel, dificultando com que os programadores experientes, e principalmente os que estão iniciando, se atentem a tecnologias periféricas, que, mesmo em desenvolvimento, apresentam ganhos significativos em performance - essencial no desenvolvimento em Python.

    Por vários motivos, Python não apresenta uma boa performance em comparação com outras linguagens, como, por exemplo, a queridinha do momento: Rust.

    Inspirado nisto, trago-lhes a possível solução para este problema: Polars API, a irmã urso adotiva da Pandas API.

    Este artigo tem como intuito:

    • Explicar a finalidade das APIs
    • Apontar as diferenças que acarretam no ganho de performance usando Polars
    • Apresentar comparações entre ambos os pacote

    1 - Finalidade

    Grosso modo, ambas as APIs buscam facilitar a manipulação de DataFrames (tabelas de dados), fornecendo funções, classes e métodos que simplificam os procedimentos mais realizados eu sua análise e organização.

    DataFrames são visualizados como tabelas, por isso, são definidos como uma representação gráfica tabular dos dados.

    Figura 1 - Tabela composta de alunos, matérias e notas

    image

    Fonte: Excel Easy

    Sabendo-se da principal finalidade, que ambas as APIs compartilham, o entendimento de suas principais diferenças se torna muito mais agradável.

    2 - Diferenças

    Apesar de ambas partilharem da mesma funcionalidade, elas se diferem em alguns pontos cruciais. Nota-se que, na manipulação de um DataFrame, pode se exigir o agrupamento de dados, modificação de valores, o tratamento de dados inválidos - como o NaN (not a number - não numérico) - e muitas outras operações muito custosas para o sistema por serem realizadas em arquivos enormes, de bilhões de linhas.

    Visando solucionar o problema, muitas empresas buscam soluções em Cloud (nuvem), como o Google Colab - ambiente interativo em Python - que pode ser utilizado online.

    Figura 2 - Google Colab

    image

    Fonte: Geonetcast

    Mesmo utilizando GPUs (Graphic Processing Unit - Unidade de Processamento Gráfico) poderosas, o custo das operações permanecem o mesmo, ou seja, apesar de disponibilizar-se mais recursos para serem consumidos, continuam sendo custosas, e, utilizando Pandas, permanecem sendo single-threaded, grosso modo, realizando uma tarefa por vez.

    Por ser single-threaded, Pandas acaba utilizando muita memória RAM (Random Access Memory - Memória de Acesso Aleatório) do sistema, e pouco da CPU (Central Processing Unit - Unidade Central de Processamento), o que pode ocasionar no esgotamento de recursos.

    Figura 4 - Crash por esgotamento
    image
    Fonte: Towards Data Science

    2.1 - Multi-threading

    Boa parte do ganho de performance ao se utilizar a Polars nasce de uma mudança relativamente simples: a concorrência, ou seja, realizar as instruções de maneira multi-threaded.

    Figura 5 - Pandas, baixo uso de CPU, alto uso de memoria

    image

    Figura 6 - Polars, uso de CPU mais elevado.

    image

    Fonte: Canal Jeff Heaton - Youtube (editadas pelo autor)

    Acima, tem-se o comparativo de uma operação de agrupamento, utilizando ambas as APIs, onde o arquivo possuia um bilhão de linhas. Pandas possui um elevado consumo de memoria. Entretanto, o mais impressionante se mostra no uso de CPU.

    Utilizando Pandas, quase não se consome CPU, já na segunda, observa-se picos de uso, chegando a bater cem por cento, resultado do multi-threading.

    Realizando a divisão de tarefas, o tempo de execução da operação foi cerca de dezesseis vezes menor utilizando Polars.

    2.2 - Rust

    Outro motivo da elevada performance se mostra na linguagem em que foi desenvolvida. Rust se consagrou como uma linguagem incrivelmente rápida, que chega a ser, em muitos casos, mais performática que a família C. Enquanto esta utiliza uma linguagem extremamente rápida, segura e versátil, Pandas se compõe em um misto de C, Cython e Python, sendo a ultima, em termos de velocidade, uma linguagem muito menos efetiva.

    2.3 - Lazy API

    A galinha dos ovos de ouro da Polars. Com ela, conseguimos:

    • Trabalhar com datasets maiores do que a RAM disponível, utilizando streaming
    • Aplicar otimizações de consulta automaticamente com o query optimizer
    • Localizar erros de schema (grosso modo, relação entre as colunas e os tipos de dados nela existentes) antes do processamento

    Ao contrário de sua irmã urso mais velha, Polars fornece a chamada Lazy API, que, ao contrario da Eager API, equivalente ao modo default, coleta os resultados apenas quando "necessário", evitando a execução em locais desinteressantes, pois a etapa de leitura e consulta são realizadas separadamente, resultando em ganho de performance e economia de recursos do sistema, permitindo, assim, manipular um arquivo que de outra forma esgotaria os recursos disponíveis.

    As otimizações de query são realizadas automaticamente, podendo ser executadas de uma a n vezes. Como exemplo, temos: a simplificação de expressões, ordenamento de join, e a coerção de tipos. Nota-se que há oito otimizações descritas no site oficial, entretanto, não sendo limitadas a elas.

    Para utilizar o modo Lazy, basta adicionar o método lazy() ao final

    # Eager API
    df = pl.read_csv("exemplo.csv")
    
    # Lazy API
    df = pl.read_csv("exemplo.csv").lazy()
    

    Para se coletar os resultados, deve se chamar o método collect(). Faz-se necessário salientar que alguns métodos são implicitamente lazy, como, por exemplo, scan_csv(), portanto, o código abaixo utiliza a Lazy API:

    df = pl.scan_csv('exemplo.csv')
    

    Apesar de não precisarmos acrescentar nenhum método para utilizar a Eager API, fazendo com que a mesma seja o modo "padrão", os desenvolvedores recomendam o uso da Lazy API sempre que possível, e, ate mesmo o modo Eager a utiliza por debaixo dos panos.

    Embora as diferenças acima expostas serem consideradas as mais impactantes, não são as únicas. Caso haja mais interesse sobre o assunto, sinta-se a vontade para visitar o site oficial, que possui inúmeras informações valiosas sobre a API.

    4 - Benchmarks

    Abaixo estarão expostos alguns benchmarks realizados, encontrados no site Towardsdatascience. Faz-se mister elucidar que todas as imagens foram retiradas do artigo em questão, não sendo nenhuma de autoria própria.

    imageimageimageimage imageimage

    Obviamente, todas as comparações utilizaram o mesmo código ou equivalente. Para mais informações, sugiro que visite o artigo supra citado.

    Conclusão

    O presente artigo tem como intuito apresentar um novo caminho em relação a ciência de dados. Apesar do titulo propositalmente provocativo, cada um deve utilizar aquilo que convém, seja Pandas, Polars, ou até mesmo uma terceira opção, como Dask.

    Salienta-se que a API Pandas lançou há pouco sua versão 2.0, integrando melhorias relativas a performance, inclusive utilizando a biblioteca PyArrow, utilizada pela Polars.

    Assim sendo, utilizando um ou outro, não deve, jamais, blindar-se de novas tecnologias e experiências, de modo que, assim como as APIs citadas, continuemos evoluindo.

    Compartilhe
    Comentários (1)
    Caio Meorin
    Caio Meorin - 04/07/2023 09:08

    ERRATA


    MEORIN, C. - Grosso modo, ambas as APIs buscam facilitar a manipulação de DataFrames (tabelas de dados), fornecendo funções, classes e métodos que simplificam os procedimentos mais realizados eu sua análise e organização.


    Onde se lê: eu

    Leia-se: em