# NumPy

NumPy (pronunciado /ˈnʌmpaɪ/ (numpai) o, a veces /ˈnʌmpi/ (numpi)) es una biblioteca para el lenguaje de programación Python que da soporte para crear vectores y matrices grandes multidimensionales, junto con una gran colección de funciones matemáticas de alto nivel para operar con ellas. El precursor de NumPy, Numeric, fue creado originalmente por Jim Hugunin con contribuciones de varios otros desarrolladores. En 2005, Travis Oliphant creó NumPy incorporando características de la competencia Numarray en Numeric, con amplias modificaciones. NumPy es un software de código abierto y cuenta con muchos colaboradores.

## Historia

El lenguaje de programación Python no fue diseñado originalmente para computación numérica, pero atrajo la atención de la comunidad científica y de ingeniería desde el principio. En 1995 se fundó el grupo de interés especial (SIG) matrix-sig con el objetivo de definir un paquete de computación de vectores; entre sus miembros se encontraba el diseñador y mantenedor de Python Guido van Rossum, quien extendió la sintaxis de Python (en particular la sintaxis de indexación) para facilitar la computación de vectores.
Jim Fulton completó una implementación de un paquete para matrices, luego generalizado por Jim Hugunin y llamado Numeric (también conocido como las "extensiones numéricas de Python" o "NumPy"). Hugunin, estudiante de posgrado en el Instituto de Tecnología de Massachusetts (MIT), $^{:10}$se unió a la Corporación para Iniciativas de Investigación Nacional (CNRI) en 1997 para trabajar en JPython, dejando a Paul Dubois del Laboratorio Nacional Lawrence Livermore (LLNL) para asumir el cargo de mantenedor. $^{:10}$Otros colaboradores tempranos incluyen a David Ascher, Konrad Hinsen y Travis Oliphant. $^{:10}$
Se escribió un nuevo paquete llamado Numarray como reemplazo más flexible de Numeric. Al igual que Numeric, actualmente también está obsoleto. Numarray tenía operaciones más rápidas para matrices grandes, pero era más lento que Numeric para las pequeñas, por lo que durante un tiempo ambos paquetes se usaron en paralelo para diferentes casos de uso. La última versión de Numeric (v24.2) se publicó el 11 de noviembre de 2005, mientras que la última versión de Numarray (v1.5.2) se publicó el 24 de agosto de 2006.
Había un deseo de incluir Numeric en la biblioteca estándar de Python, pero Guido van Rossum decidió que el código no se podía mantener en su estado en ese momento. A principios de 2005, el desarrollador de NumPy, Travis Oliphant, quería unificar la comunidad en torno a un solo paquete de arreglo y portó las características de Numarray a Numeric, lanzando el resultado como NumPy 1.0 en 2006. Este nuevo proyecto formaba parte de SciPy. Para evitar instalar el gran paquete SciPy solo para obtener un objeto de matriz, este nuevo paquete se separó y se llamó NumPy. El soporte para Python 3 se añadió en 2011 con la versión 1.5.0 de NumPy.
En 2011, PyPy comenzó a desarrollar una implementación de la API NumPy para PyPy. Todavía no es totalmente compatible con NumPy.

## Características

NumPy apunta a la implementación de Python de referencia CPython, un intérprete de código de bytes no optimizador. Los algoritmos matemáticos escritos para esta versión de Python a menudo se ejecutan mucho más lento que los equivalentes compilados. NumPy aborda el problema de la lentitud en parte al proporcionar matrices multidimensionales, funciones y operadores que operan de manera eficiente en matrices, lo que requiere reescribir algo de código, principalmente bucles internos, usando NumPy.
El uso de NumPy en Python brinda una funcionalidad comparable a MATLAB, ya que ambos se interpretan, y ambos permiten al usuario escribir programas rápidos siempre que la mayoría de las operaciones funcionen en vectores o matrices en lugar de escalares. En comparación, MATLAB cuenta con una gran cantidad de cajas de herramientas adicionales, en particular Simulink, mientras que NumPy está intrínsecamente integrado con Python, un lenguaje de programación más moderno y completo. Además, se encuentran disponibles paquetes complementarios de Python; SciPy es una biblioteca que agrega más funcionalidad similar a MATLAB y Matplotlib es un paquete de trazado que proporciona una funcionalidad de trazado similar a MATLAB. Internamente, tanto MATLAB como NumPy se basan en BLAS y LAPACK para cálculos de álgebra lineal eficientes.
Los bindings de Python de la ampliamente utilizada biblioteca de visión por computadora OpenCV utilizan matrices NumPy para almacenar y operar con datos. Dado que las imágenes con múltiples canales se representan simplemente como matrices tridimensionales, indexar, cortar o enmascarar con otras matrices son formas muy eficientes de acceder a píxeles específicos de una imagen. La matriz NumPy como estructura de datos universal en OpenCV para imágenes, puntos de características extraídos, núcleos de filtrado y muchos más simplifica enormemente el flujo de trabajo de programación y la depuración .

### La estructura de datos ndarray

La funcionalidad principal de NumPy es su estructura de datos "ndarray", para una matriz de n dimensiones. Estas matrices son vistas escalonadas de la memoria. A diferencia de la estructura de datos de lista incorporada de Python, estas matrices se escriben de forma homogénea: todos los elementos de una única matriz deben ser del mismo tipo.
Dichas matrices también pueden ser vistas en búferes de memoria asignados por extensiones de C o C++, Cython y Fortran al intérprete CPython sin la necesidad de copiar datos, lo que brinda un mayor grado de compatibilidad con las bibliotecas numéricas existentes. Esta funcionalidad es explotada por el paquete SciPy, que incluye varias de estas bibliotecas (en particular BLAS y LAPACK). NumPy tiene soporte incorporado para ndarrays mapeados en memoria.

### Limitaciones

Insertar o agregar entradas a una matriz no es tan trivialmente posible como lo es con las listas de Python. La rutina np.pad(...) para extender matrices crea nuevas matrices con la forma deseada y los valores de relleno, copia la matriz dada en la nueva y la devuelve. La operación np.concatenate([a1, a2])de NumPy no vincula realmente las dos matrices, sino que devuelve una nueva, llena con las entradas de ambas matrices dadas en secuencia. La remodelación de las dimensiones de una matriz con np.reshape(...) solo es posible siempre que el número de elementos de la matriz no cambie. Estas circunstancias se originan en el hecho de que las matrices de NumPy deben ser vistas en búferes de memoria contiguos. Un paquete de reemplazo llamado Blaze intenta superar esta limitación.
Los algoritmos que no se pueden expresar como una operación vectorizada normalmente se ejecutarán lentamente porque deben implementarse en "Python puro", mientras que la vectorización puede aumentar la complejidad de la memoria de algunas operaciones de constante a lineal, porque se deben crear matrices temporales que sean tan grandes como las entradas. Varios grupos han implementado la compilación en tiempo de ejecución de código numérico para evitar estos problemas. Las soluciones de código abierto que interactúan con NumPy incluyen scipy.weave, numexpr y Numba. Cython y Pythran son otras alternativas de compilación estática.