NumPY - o motor por tras do Python Pandas

NumPY - o motor por trás do Python Pandas

O Pandas domina grande parte das discussões e fluxos de trabalho para manipulação de dados tabulares, mas o NumPy é o motor de alto desempenho subjacente que impulsiona não apenas o Pandas, mas grande parte do ecossistema de computação científica em Python.

O NumPy (Numerical Python) é a biblioteca fundamental para computação numérica em Python. Ele fornece um objeto array multidimensional de alto desempenho (ndarray) e ferramentas para trabalhar com esses arrays. Sua relevância transcende a computação científica pura, sendo a base para bibliotecas de análise de dados como Pandas, bibliotecas de machine learning como scikit-learn, e frameworks de deep learning como TensorFlow e PyTorch (que utilizam estruturas compatíveis com arrays NumPy ou o próprio NumPy nos bastidores).

A eficiência do NumPy vem da sua implementação principal em C e Fortran. Isso garante que operações em arrays sejam executadas em velocidades comparáveis a código compilado, evitando os gargalos de desempenho inerentes aos loops e estruturas de dados nativas do Python (como listas) ao lidar com grandes volumes de dados numéricos.

O ndarray - "n-dimensional array"

As características principais incluem:

  1. Homogeneidade: Todos os elementos de um ndarray devem ter o mesmo tipo de dado (e.g., inteiros de 64 bits, floats de 32 bits). Essa homogeneidade é crucial para permitir operações vetorizadas eficientes e armazenamento contíguo na memória.
  2. Tamanho Fixo: Uma vez criado, o tamanho de um ndarray é fixo. Alterações de tamanho geralmente resultam na criação de um novo array.
  3. Multidimensionalidade: Suporta arrays com qualquer número de dimensões (vetores 1D, matrizes 2D, tensores 3D ou mais).
  4. Operações Vetorizadas: O NumPy permite aplicar operações matemáticas e lógicas a arrays inteiros de forma eficiente, sem a necessidade de escrever loops explícitos em Python. Isso é conhecido como "vetorização" e é a principal fonte de ganho de desempenho. Exemplos incluem adição de arrays, multiplicação elemento a elemento, aplicação de funções universais (ufuncs) como np.sin(), np.exp(), etc.
  5. Broadcasting: Mecanismo poderoso que permite que arrays com formas diferentes sejam combinados em operações aritméticas, seguindo um conjunto específico de regras. Isso evita a necessidade de replicar dados explicitamente para que as formas sejam compatíveis.
  6. Armazenamento Contíguo (idealmente): Frequentemente, os dados de um ndarray são armazenados em um bloco contíguo de memória. Isso melhora a localidade de cache da CPU e permite que algoritmos otimizados (escritos em C/Fortran) processem os dados de forma muito eficiente.

Threads OK! - da documentação.

NumPy supports use in a multithreaded context via the threading module in the standard library. Many NumPy operations release the GIL, so unlike many situations in Python, it is possible to improve parallel performance by exploiting multithreaded parallelism in Python.
The easiest performance gains happen when each worker thread owns its own array or set of array objects, with no data directly shared between threads. Because NumPy releases the GIL for many low-level operations, threads that spend most of the time in low-level code will run in parallel.
... veja os links abaixo

e também sem o GIL ...

Starting with NumPy 2.1 and CPython 3.13, NumPy also has experimental support for python runtimes with the GIL disabled. See https://py-free-threading.github.io for more information about installing and using free-threaded Python, as well as information about supporting it in libraries that depend on NumPy.
... veja os links abaixo

Não somente o Pandas, mas o NumPy serve como a base para um vasto ecossistema de bibliotecas científicas e de ciência de dados em Python, incluindo SciPy, Matplotlib, Scikit-learn, TensorFlow e PyTorch. Seus arrays são o formato de intercâmbio de dados de facto.

Pandas para explorar, NumPy para produção

É fundamental compreender que o NumPy e o Pandas são complementares. Pandas foi construído sobre NumPy para fornecer funcionalidades de alto nível para a manipulação de dados. Tratamento avançado de valores ausentes, agrupamento, funcionalidades e atalhos para manipulação de séries temporais e etc.

O Pandas não é a solução ideal para produção, apesar de seu grande poder.

Aqui na Necto Systems, não é raro fazermos a exploração e validação do processo usando Jupyter Notebooks e Pandas, estes continuam fazendo parte da documentação, mas não da solução entregue e publicado para produção.

Vale a pena citar que o contexto da Necto Systems, de forma mais genérica, entregamos um sistema para a manutenção dos processos de análises de dados. Em geral, não é somente o resultado de uma pesquisa ou tratamento de dados, mas uma ferramenta de software para extração, transformação e carga de dados periódica, relatórios atualizados etc. Em geral o produto final é um sistema e não "uma análise de dados".
O Pandas juntamente com Jupyter Notebook é uma excelente ferramenta exploratória, que agiliza a exploração em si e a documentação do processo de extração e transformação dos dados.

Após o estudo, as regras para a extração, transformação e carga ("E.T.L." em EN) do dado legado são implementadas em um sistema Python (ou sistemas), possível mente com serviços em paralelo e integrado a outros serviços existente.

Um DataFrame Pandas armazena seus dados internamente em blocos de memória. Quando as colunas têm o mesmo tipo de dado, esses blocos são frequentemente armazenados como arrays NumPy. Operações em colunas ou DataFrames inteiros no Pandas são, em muitos casos, traduzidas internamente para operações vetorizadas do NumPy nos blocos de dados subjacentes. Por exemplo, somar duas colunas numéricas em um DataFrame Pandas resulta em uma operação de adição de arrays NumPy nos bastidores. Isso permite que Pandas herde o desempenho do NumPy para operações numéricas, enquanto adiciona a conveniência do gerenciamento de rótulos e dados heterogêneos.

Como decidir, Pandas ou somente a biblioteca NumPy ?

  • Os dados são intrinsecamente arrays numéricos, álgebra linear, transformadas ou funções matemáticas universais.
  • A performance e o uso de memória por elemento são críticos, e o overhead de um DataFrame Pandas é significativo para o caso de uso.
  • Estamos integrando com outras bibliotecas que operam diretamente em arrays NumPy (o que é muito comum no ecossistema científico Python).
  • Os scripts devem ser integrados em uma aplicação/sistema maior sendo executado periodicamente como "job" ou sob demanda.

estas características de um sistema podem ser indicadores para o uso direto da biblioteca NumPy, e onde o Pandas pode implicar em um "ovehead".

Uma vez definida a lógica do ETL é possível "quebrá-la" em várias partes e passar aquele processamento a ferramenta mais eficiente

  1. Se banco de dados, executar queries mais otimizadas e que contribuam diretamente com o tipo de dados/array do NumPy.
  2. Tratar outros formatos de dados (fora do DB) em lotes, assim que disponíveis a parte do fluxo principal do processo.
  3. Scripts independentes para análise e tratamento de cada entrada de dados.
  4. Tratamento de dados nulos, alertas ou logs para dados com valores "inválidos".
  5. gerando uma base de dados otimizada para o contexto da tomada de decisão para qual o processo desenhado.

Cada Caso, um caso

Como cientistas de dados ou como analistas, devemos ser capazes de identificar as oportunidades de cada caso e utilizar a melhor ferramenta para o serviço dentro dos parâmetros de qualidade exigidos.

Desacoplar etapas do processo de ETL é a chave para reduzir a complexidade e as dependências daquele subsistema. Isso não só facilita a manutenção, como também a torna mais barata.

Sejam as mudanças futuras definidas pelo crescimento dos dados ou sua transformação, um sistema desacoplado com etapas bem definidas trará facilidade para as atualizações,

E utilizando o NumPy diretamente, mantemos os ganhos de performance e facilidade da manipulação da massa de dados.

links: