NumPy (pronuncia-se "num-pai") é uma biblioteca para a linguagem de programação Python que adiciona suporte a arrays e matrizes grandes e multidimensionais, juntamente com uma coleção de funções matemáticas de alto nível para operar nesses arrays. É um software de código aberto com muitos colaboradores e é patrocinado financeiramente pela NumFOCUS. NumPy é um componente central do ecossistema científico de Python, sustentando bibliotecas como SciPy e Matplotlib, e é amplamente utilizado em áreas que vão desde análise de dados até Machine learning e Deep learning.
História
O predecessor do NumPy, o Numeric, foi originalmente criado por Jim Hugunin com contribuições de vários outros desenvolvedores. Em 2005, Travis Oliphant criou o NumPy incorporando características do Numarray, um concorrente, ao Numeric, com modificações extensas. O primeiro lançamento, NumPy 1.0, ocorreu em 2006. Desde então, o NumPy evoluiu para suportar Python 3 (a partir da versão 1.5.0 em 2011) e se tornou uma ferramenta padrão para computação numérica em Python.
A linguagem de programação Python não foi originalmente projetada para computação numérica, mas atraiu a atenção da comunidade científica e de engenharia desde cedo. Em 1995, o grupo de interesse especial matrix-sig foi fundado com o objetivo de definir um pacote de arrays. Entre seus membros estava o designer e mantenedor do Python, Guido van Rossum, que estendeu a sintaxe do Python, particularmente a sintaxe de indexação, para facilitar a programação com arrays.
Uma implementação de um pacote de matrizes foi concluída por Jim Fulton e depois expandida para suportar arrays multidimensionais por Jim Hugunin, que o chamou de Numeric (também conhecido como "Numerical Python extensions" ou "NumPy"). Hugunin, um estudante de pós-graduação do Instituto de Tecnologia de Massachusetts (MIT), juntou-se à Corporação para Iniciativas de Pesquisa Nacional (CNRI) em 1997 para trabalhar no JPython, deixando Paul Dubois do Laboratório Nacional Lawrence Livermore (LLNL) como mantenedor. Outros colaboradores iniciais incluíram David Ascher, Konrad Hinsen e Travis Oliphant.
Um novo pacote chamado Numarray foi escrito como um substituto mais flexível para o Numeric. Ele tinha operações mais rápidas para arrays grandes, mas era mais lento para arrays pequenos, então, por um tempo, ambos os pacotes foram usados em paralelo para diferentes casos de uso. A última versão do Numeric (v24.2) foi lançada em 11 de novembro de 2005, enquanto a última versão do numarray (v1.5.2) foi lançada em 24 de agosto de 2006. Havia o desejo de incluir o Numeric na biblioteca padrão do Python, mas Guido van Rossum decidiu que o código não era mantível no estado em que se encontrava.
No início de 2005, Travis Oliphant queria unificar a comunidade em torno de um único pacote de arrays. Ele portou as características do Numarray para o Numeric e lançou o resultado como NumPy 1.0 em 2006. Este novo projeto fazia parte do SciPy, mas, para evitar a instalação do grande pacote SciPy apenas para obter um objeto de array, foi separado e chamado de NumPy. Em 2011, o PyPy iniciou o desenvolvimento de uma implementação da API do NumPy para o PyPy; até 2023, ela ainda não é totalmente compatível com o NumPy.
Características
O NumPy tem como alvo a implementação de referência do Python, o CPython, que é um interpretador de bytecode não otimizado. Algoritmos matemáticos escritos para esta versão do Python muitas vezes rodam muito mais devagar do que equivalentes compilados, devido à ausência de otimização do compilador. O NumPy aborda essa lentidão em parte fornecendo arrays multidimensionais e operadores e funções que operam eficientemente nesses arrays. Usar o NumPy exige reescrever parte do código, principalmente os loops internos, para usar arrays.
Usar NumPy em Python oferece funcionalidade comparável ao MATLAB, já que ambos são interpretados e ambos permitem que o usuário escreva programas rápidos, desde que a maioria das operações trabalhe com arrays ou matrizes em vez de escalares. O MATLAB possui um grande número de toolboxes adicionais, notavelmente o Simulink, enquanto o NumPy é intrinsecamente integrado ao Python, uma linguagem de programação mais moderna e completa. Pacotes complementares em Python estão disponíveis: o SciPy adiciona mais funcionalidades semelhantes ao MATLAB, e o Matplotlib fornece plotagem semelhante à do MATLAB. Embora o MATLAB possa realizar operações com matrizes esparsas, o NumPy sozinho não pode, exigindo o uso da biblioteca scipy.sparse. Internamente, tanto o MATLAB quanto o NumPy dependem de BLAS e LAPACK para cálculos eficientes de álgebra linear.
Bindings em Python para a biblioteca de visão computacional amplamente utilizada OpenCV utilizam arrays do NumPy para armazenar e operar sobre dados. Como imagens com múltiplos canais são simplesmente representadas como arrays tridimensionais, indexação, fatiamento ou mascaramento com outros arrays são formas eficientes de acessar pixels específicos. O array do NumPy como estrutura de dados universal no OpenCV para imagens, pontos de características extraídos, kernels de filtro e muito mais simplifica o fluxo de trabalho de programação e a depuração. Importante: muitas operações do NumPy liberam o global interpreter lock, o que permite processamento multithread. O NumPy também fornece uma API em C, permitindo que o código Python interopere com bibliotecas externas escritas em linguagens de baixo nível.
A Estrutura de Dados ndarray
A funcionalidade central do NumPy é sua estrutura de dados "ndarray" (array n-dimensional). Esses arrays são visões strided sobre a memória. Em contraste com a estrutura de dados lista embutida do Python, os arrays são homogeneamente tipados: todos os elementos de um único array devem ser do mesmo tipo. Tais arrays também podem ser visões sobre buffers de memória alocados por extensões em C/C++ e Fortran para o interpretador CPython, sem a necessidade de copiar dados, dando um grau de compatibilidade com bibliotecas numéricas existentes. Essa funcionalidade é explorada pelo pacote SciPy, que encapsula várias dessas bibliotecas (notavelmente BLAS e LAPACK). O NumPy tem suporte embutido para ndarrays mapeados em memória (memory-mapped).
Limitações
Inserir ou anexar entradas em um array não é tão trivialmente possível quanto é com as listas do Python. A rotina np.pad para estender arrays na verdade cria novos arrays com a forma desejada e valores de preenchimento, copia o array dado para o novo e o retorna. Da mesma forma, np.concatenate([a1, a2]) não liga os dois arrays, mas retorna um novo preenchido com as entradas de ambos. Redimensionar a dimensionalidade de um array com np.reshape só é possível se o número de elementos não mudar. Essas circunstâncias se originam do fato de que os arrays do NumPy devem ser visões sobre buffers de memória contíguos.
Algoritmos que não são expressáveis como uma operação vetorizada tipicamente rodarão lentamente porque precisam ser implementados em "Python puro", enquanto a vetorização pode aumentar a complexidade de memória de algumas operações de constante para linear, porque arrays temporários devem ser criados que são tão grandes quanto as entradas. A compilação em tempo de execução de código numérico foi implementada por vários grupos para evitar esses problemas; soluções de código aberto que interoperam com o NumPy incluem numexpr e Numba. Cython e Pythran são opções de compilação estática que também podem acelerar código baseado em NumPy.
Aplicações e Impacto
O NumPy é fundamental para muitos campos científicos e orientados a dados. Ele fornece as operações de array que sustentam frameworks e bibliotecas de Machine learning, como TensorFlow e PyTorch, que são usados para construir modelos de redes neurais e arquiteturas transformers. Na pesquisa de inteligência artificial, os arrays do NumPy são frequentemente usados para pré-processamento de dados, extração de características e implementação de algoritmos do zero. A eficiência e flexibilidade da biblioteca a tornaram uma ferramenta padrão em ambientes acadêmicos e industriais, do MIT e Stanford a empresas como Google e Amazon.
A influência do NumPy se estende além da computação científica tradicional. Ele é usado em visão computacional para processamento de imagens, em processamento de linguagem natural para lidar com embeddings de palavras, e em aprendizado por reforço para gerenciar espaços de estados. Sua integração com OpenCV e outras bibliotecas simplificou fluxos de trabalho em robótica e sistemas autônomos, como os desenvolvidos pela Waymo e Tesla. Em 2023, o NumPy permanece uma das bibliotecas Python mais baixadas, refletindo seu papel central no ecossistema computacional moderno.