stringtranslate.com

NumPy

NumPy (pronunciado /ˈnʌmpaɪ/ NUM - py ) es una biblioteca para el lenguaje de programación Python , que agrega soporte para matrices y arreglos multidimensionales grandes , junto con una gran colección de funciones matemáticas de alto nivel para operar en estos arreglos. [3] El predecesor de NumPy, Numeric, fue creado originalmente por Jim Hugunin con contribuciones de varios otros desarrolladores. En 2005, Travis Oliphant creó NumPy incorporando características del competidor Numarray en Numeric, con amplias modificaciones. NumPy es un software de código abierto y tiene muchos contribuyentes. NumPy es un proyecto patrocinado fiscalmente por NumFOCUS. [4]

Historia

matriz-sig

El lenguaje de programación Python no fue diseñado originalmente para el cálculo numérico, 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 matrices ; 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 [5] ) para facilitar la computación de matrices . [6]

Numérico

Jim Fulton completó una implementación de un paquete de matrices, que luego fue generalizado [ se necesita más explicación ] por Jim Hugunin y llamado Numeric [6] (también conocido como las "extensiones numéricas de Python" o "NumPy"), con influencias de la familia de lenguajes APL , Basis, MATLAB , FORTRAN , S y S+ , y otros. [7] [8] Hugunin, un estudiante de posgrado en el Instituto Tecnológico de Massachusetts (MIT), [8] : 10  se unió a la Corporación para Iniciativas Nacionales de Investigación (CNRI) en 1997 para trabajar en JPython , [6] dejando a Paul Dubois del Laboratorio Nacional Lawrence Livermore (LLNL) para que asumiera el cargo de mantenedor. [8] : 10  Otros contribuyentes tempranos incluyen a David Ascher, Konrad Hinsen y Travis Oliphant . [8] : 10 

Numeración

Se escribió un nuevo paquete llamado Numarray como reemplazo más flexible de Numeric. [9] Al igual que Numeric, también está en desuso. [10] [11] Numarray tenía operaciones más rápidas para matrices grandes, pero era más lento que Numeric en matrices pequeñas, [12] 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 lanzó el 11 de noviembre de 2005, mientras que la última versión de numarray (v1.5.2) se lanzó el 24 de agosto de 2006. [13]

Existía el deseo de incluir Numeric en la biblioteca estándar de Python, pero Guido van Rossum decidió que el código no era mantenible en su estado en ese momento. [ ¿cuándo? ] [14]

NumPy

A principios de 2005, el desarrollador de NumPy, Travis Oliphant, quiso unificar la comunidad en torno a un único paquete de matrices y trasladó las características de Numarray a Numeric, publicando el resultado como NumPy 1.0 en 2006. [9] 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 denominó NumPy. La compatibilidad con Python 3 se agregó en 2011 con la versión 1.5.0 de NumPy. [15]

En 2011, PyPy comenzó a desarrollar una implementación de la API NumPy para PyPy. [16] A partir de 2023, todavía no es totalmente compatible con NumPy. [17]

Características

NumPy apunta a la implementación de referencia CPython de Python, que es un intérprete de bytecode no optimizador . Los algoritmos matemáticos escritos para esta versión de Python suelen ejecutarse mucho más lento que sus equivalentes compilados debido a la ausencia de optimización del compilador. NumPy aborda el problema de la lentitud en parte al proporcionar matrices multidimensionales y funciones y operadores que operan de manera eficiente en matrices; su uso requiere reescribir parte del código, principalmente bucles internos , utilizando NumPy.

El uso de NumPy en Python proporciona una funcionalidad comparable a MATLAB , ya que ambos son interpretados [18] y ambos permiten al usuario escribir programas rápidos siempre que la mayoría de las operaciones funcionen en arreglos 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, hay paquetes complementarios de Python disponibles; SciPy es una biblioteca que agrega más funcionalidad similar a MATLAB y Matplotlib es un paquete de gráficos que proporciona una funcionalidad de gráficos similar a MATLAB. Aunque Matlab puede realizar operaciones de matriz dispersa, Numpy por sí solo no puede realizar tales operaciones y requiere el uso de la biblioteca scipy.sparse. Internamente, tanto MATLAB como NumPy dependen de BLAS y LAPACK para realizar cálculos de álgebra lineal eficientes .

Los enlaces de Python de la biblioteca de visión artificial OpenCV, ampliamente utilizada , utilizan matrices NumPy para almacenar y operar con datos. Dado que las imágenes con múltiples canales se representan simplemente como matrices tridimensionales, la indexación, el corte o el enmascaramiento 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 característicos extraídos , núcleos de filtro y mucho más simplifica enormemente el flujo de trabajo de programación y depuración . [ cita requerida ]

Es importante destacar que muchas operaciones de NumPy liberan el bloqueo del intérprete global , lo que permite el procesamiento multiproceso. [19]

NumPy también proporciona una API C, que permite que el código Python interopere con bibliotecas externas escritas en lenguajes de bajo nivel. [20]

La estructura de datos ndarray

La funcionalidad principal de NumPy es su estructura de datos "ndarray", para matrices n -dimensionales . Estas matrices son vistas escalonadas en la memoria. [9] A diferencia de la estructura de datos de lista incorporada de Python, estas matrices tienen tipos homogéneos: todos los elementos de una sola matriz deben ser del mismo tipo.

Estas matrices también pueden visualizarse en búferes de memoria asignados por extensiones de C / C++ , Python y Fortran al intérprete CPython sin necesidad de copiar datos, lo que proporciona un grado de compatibilidad con las bibliotecas numéricas existentes. Esta funcionalidad es explotada por el paquete SciPy, que encapsula varias de estas bibliotecas (especialmente BLAS y LAPACK). NumPy tiene soporte integrado para ndarrays mapeados en memoria . [9]

Limitaciones

Insertar o agregar entradas a una matriz no es tan trivialmente posible como lo es con las listas de Python. La np.pad(...)rutina para extender matrices en realidad crea nuevas matrices de la forma deseada y los valores de relleno, copia la matriz dada en la nueva y la devuelve. np.concatenate([a1,a2])La operación de NumPy en realidad no vincula las dos matrices, sino que devuelve una nueva, llena con las entradas de ambas matrices dadas en secuencia. Reformar la dimensionalidad de una matriz con np.reshape(...)solo es posible mientras el número de elementos en la matriz no cambie. Estas circunstancias se originan del hecho de que las matrices de NumPy deben ser vistas en búferes de memoria contiguos .

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 interoperan con NumPy incluyen numexpr [21] y Numba . [22] Cython y Pythran son alternativas de compilación estática a estas.

Muchas aplicaciones informáticas científicas modernas a gran escala tienen requisitos que exceden las capacidades de las matrices NumPy. Por ejemplo, las matrices NumPy generalmente se cargan en la memoria de una computadora , que puede tener capacidad insuficiente para el análisis de grandes conjuntos de datos . Además, las operaciones NumPy se ejecutan en una sola CPU . Sin embargo, muchas operaciones de álgebra lineal se pueden acelerar al ejecutarlas en grupos de CPU o de hardware especializado, como GPU y TPU , de los que dependen muchas aplicaciones de aprendizaje profundo . Como resultado, han surgido varias implementaciones de matrices alternativas en el ecosistema científico de Python en los últimos años, como Dask para matrices distribuidas y TensorFlow o JAX para cálculos en GPU. Debido a su popularidad, estos a menudo implementan un subconjunto de la API de NumPy o lo imitan, de modo que los usuarios pueden cambiar la implementación de su matriz con cambios mínimos en su código requerido. [3] Una biblioteca llamada CuPy , [23] acelerada por el marco CUDA de Nvidia , también ha demostrado potencial para una computación más rápida, siendo un " reemplazo directo " de NumPy. [24]

Ejemplos

importar  numpy  como  np desde  numpy.random  importar  rand desde  numpy.linalg  importar  solve ,  inv a = np . array ([[ 1 , 2 , 3 , 4 ],[ 3 , 4 , 6 , 7 ],[ 5 , 9 , 0 , 5 ]]) a . transpose ()

Operaciones básicas

>>>  a  =  np . array ([ 1 ,  2 ,  3 ,  6 ]) >>>  b  =  np . linspace ( 0 ,  2 ,  4 )  # crea una matriz con cuatro puntos espaciados de manera uniforme comenzando con 0 y terminando con 2. >>>  c  =  a  -  b >>>  c array ([  1.  ,  1.33333333 ,  1.66666667 ,  4.  ]) >>>  a ** 2 array ([  1 ,  4 ,  9 ,  36 ])

Funciones universales

>>>  a  =  np . linspace ( - np . pi ,  np . pi ,  100 )  >>>  b  =  np . sin ( a ) >>>  c  =  np . cos ( a ) >>> >>>  # Las funciones pueden tomar números y matrices como parámetros. >>>  np . sin ( 1 ) 0.8414709848078965 >>>  np . sin ( np . array ([ 1 ,  2 ,  3 ])) array ([ 0.84147098 ,  0.90929743 ,  0.14112001 ])

Álgebra lineal

>>>  de  numpy.random  importe  rand >>>  de  numpy.linalg  importe  solve ,  inv >>>  a  =  np . array ([[ 1 ,  2 ,  3 ],  [ 3 ,  4 ,  6.7 ],  [ 5 ,  9.0 ,  5 ]]) >>>  a . transpose () matriz ([[  1  ,  3  ,  5  ],  [  2  ,  4  ,  9  ],  [  3  ,  6,7 ,  5  ]]) >>>  inv ( a ) matriz ([[ -2,27683616 , 0,96045198 , 0,07909605 ], [ 1,04519774 , -0,56497175 , 0,1299435 ] , [ 0,39548023 , 0,05649718 , -0,11299435 ] ] ) >>> b = np . array ([ 3 , 2 , 1 ]) >>> solve ( a , b ) # resuelve la ecuación ax = b array ([ - 4.83050847 , 2.13559322 , 1.18644068 ]) >>> c = rand ( 3 , 3 ) * 20 # crea una matriz aleatoria de 3x3 de valores dentro de [0,1] escalada por 20 >>> c array ([[ 3.98732789 , 2.47702609 , 4.71167924 ], [ 9.24410671 , 5.5240412 , 10.6468792 ], [ 10.38136661 , 8.44968437 , 15.17639591 ]]) >>> np . dot ( a , c ) # matriz de multiplicación ( [[ 53.61964114 , 38.8741616 , 71.53462537                                                 ],  [  118.4935668  ,  86.14012835 ,  158.40440712 ],  [  155.04043289 ,  104.3499231  ,  195.26228855 ]]) >>>  a  @  c  # A partir de Python 3.5 y NumPy 1.10 array ([[  53.61964114 ,  38.8741616  ,  71.53462537 ],  [  118.4935668  ,  86.14012835 ,  158.40440712 ],  [  155.04043289 ,  104.3499231  ,  195.26228855 ]])

Matrices multidimensionales

>>>  M  =  np . ceros ( forma = ( 2 ,  3 ,  5 ,  7 ,  11 )) >>>  T  =  np . transponer ( M ,  ( 4 ,  2 ,  1 ,  3 ,  0 )) >>>  T . forma ( 11 ,  5 ,  3 ,  7 ,  2 )

Incorporación con OpenCV

>>>  import  numpy  as  np >>>  import  cv2 >>>  r  =  np . reshape ( np . arange ( 256 * 256 ) % 256 ,( 256 , 256 ))  # Matriz de 256x256 píxeles con un gradiente horizontal de 0 a 255 para el canal de color rojo >>>  g  =  np . zeros_like ( r )  # Matriz del mismo tamaño y tipo que r pero llena de 0 para el canal de color verde >>>  b  =  r . T  # r transpuesto dará un gradiente vertical para el canal de color azul >>>  cv2 . imwrite ( 'gradients.png' ,  np . dstack ([ b , g , r ]))  # Las imágenes OpenCV se interpretan como BGR, la matriz apilada en profundidad se escribirá en un archivo PNG RGB de 8 bits llamado 'gradients.png' True

Búsqueda del vecino más cercano

Algoritmo iterativo de Python y versión vectorizada de NumPy.

>>>  # # # Python iterativo puro # # # >>>  puntos  =  [[ 9 , 2 , 8 ],[ 4 , 7 , 2 ],[ 3 , 4 , 4 ],[ 5 , 6 , 9 ],[ 5 , 0 , 7 ],[ 8 , 2 , 7 ],[ 0 , 3 , 2 ],[ 7 , 3 , 0 ],[ 6 , 1 , 1 ],[ 2 , 9 , 6 ]] >>>  qPunto  =  [ 4 , 5 , 3 ] >>>  minIdx  =  - 1 >>>  minDist  =  - 1 >>>  para  idx ,  punto  en  enumerate ( puntos ):  # iterar sobre todos los puntos ...  dist  =  suma ([( dp - dq ) ** 2  para  dp , dq  en  zip ( punto , qPoint )]) ** 0.5  # calcula la distancia euclidiana de cada punto a q ...  si  dist  <  minDist  o  minDist  <  0 :  # si es necesario, actualiza la distancia mínima y el índice del punto correspondiente ...  minDist  =  dist ...  minIdx  =  idx>>>  print ( f 'Punto más cercano a q: { puntos [ minIdx ] } ' ) Punto más cercano  a q : [ 3 , 4 , 4 ]     >>>  # # # Vectorización NumPy equivalente # # # >>>  import  numpy  as  np >>>  points  =  np . array ([[ 9 , 2 , 8 ],[ 4 , 7 , 2 ],[ 3 , 4 , 4 ],[ 5 , 6 , 9 ],[ 5 , 0 , 7 ],[ 8 , 2 , 7 ],[ 0 , 3 , 2 ],[ 7 , 3 , 0 ],[ 6 , 1 , 1 ],[ 2 , 9 , 6 ]]) >>>  qPoint  =  np . array ([ 4 , 5 , 3 ]) >>>  minIdx  =  np . argmin ( np.linalg.norm ( points - qPoint , axis = 1 )) # calcula todas las distancias euclidianas a la vez y devuelve el índice de la más pequeña >>> print ( f ' Punto más cercano a q: { points [ minIdx ] } ' ) Punto más cercano a q : [ 3 4 4 ]        

F2PY

Envuelva rápidamente el código nativo para crear scripts más rápidos. [25] [26] [27]

! Ejemplo de llamada de código nativo de Python Fortran ! f2py -c -m foo *.f90 ! Compila Fortran en un módulo nombrado de Python usando declaraciones intent ! Subrutinas Fortran solamente, no funciones; más fácil que JNI con contenedor C ! requiere gfortran y make subrutine ftest ( a , b , n , c , d ) implicit none whole , intent ( in ) :: a , b , n whole , intent ( out ) :: c , d whole :: i c = 0 do i = 1 , n c = a + b + c end do d = ( c * n ) * ( - 1 ) end subrutine ftest                                         
>>> import  numpy  como  np >>> import  foo >>> a  =  foo . ftest ( 1 ,  2 ,  3 )  # o c,d = en lugar de ac y ad >>> print ( a ) (9,-27) >>> help ( 'foo.ftest' )  # foo.ftest.__doc__

Véase también

Referencias

  1. ^ "Versión 2.1.2". 5 de octubre de 2024. Consultado el 22 de octubre de 2024 .
  2. ^ "NumPy — NumPy". numpy.org . Desarrolladores de NumPy.
  3. ^ ab Charles R. Harris; K. Jarrod Millman; Stéfan J. van der Walt; et al. (16 de septiembre de 2020). "Programación de matrices con NumPy" (PDF) . Naturaleza . 585 (7825): 357–362. arXiv : 2006.10256 . doi :10.1038/S41586-020-2649-2. ISSN  1476-4687. PMC 7759461 . PMID  32939066. Wikidata  Q99413970. 
  4. ^ "Proyectos patrocinados por NumFOCUS". NumFOCUS . Consultado el 25 de octubre de 2021 .
  5. ^ "Indexación: manual de NumPy v1.20". numpy.org . Consultado el 6 de abril de 2021 .
  6. ^ abc Millman, K. Jarrod; Aivazis, Michael (2011). "Python para científicos e ingenieros". Computing in Science and Engineering . 13 (2): 9–12. Bibcode :2011CSE....13b...9M. doi :10.1109/MCSE.2011.36. Archivado desde el original el 19 de febrero de 2019 . Consultado el 7 de julio de 2014 .
  7. ^ Travis Oliphant (2007). "Python para computación científica" (PDF) . Computación en ciencia e ingeniería . Archivado desde el original (PDF) el 14 de octubre de 2013. Consultado el 12 de octubre de 2013 .
  8. ^ abcd David Ascher; Paul F. Dubois; Konrad Hinsen; Jim Hugunin; Travis Oliphant (1999). "Python numérico" (PDF) .
  9. ^ abcd van der Walt, Stéfan; Colbert, S. Chris; Varoquaux, Gaël (2011). "La matriz NumPy: una estructura para el cálculo numérico eficiente". Computación en Ciencias e Ingeniería . 13 (2). IEEE: 22. arXiv : 1102.1523 . Código Bib : 2011CSE....13b..22V. doi :10.1109/MCSE.2011.37. S2CID  16907816.
  10. ^ "Página de inicio de Numarray" . Consultado el 24 de junio de 2006 .
  11. ^ Travis E. Oliphant (7 de diciembre de 2006). Guía de NumPy . Consultado el 2 de febrero de 2017 .
  12. ^ Travis Oliphant y otros desarrolladores de SciPy. «[Numpy-discussion] Status of Numeric» (Discusión sobre Numpy) . Consultado el 2 de febrero de 2017 .
  13. ^ "Archivos de Sourceforge de NumPy" . Consultado el 24 de marzo de 2008 .
  14. ^ "Historia_de_SciPy - Volcado wiki de SciPy". scipy.github.io .
  15. ^ "Notas de la versión de NumPy 1.5.0" . Consultado el 29 de abril de 2011 .
  16. ^ "Blog de estado de PyPy: actualización de estado y financiación de NumPy" . Consultado el 22 de diciembre de 2011 .
  17. ^ "Estado de NumPyPy" . Consultado el 19 de diciembre de 2023 .
  18. ^ La comunidad SciPy. «NumPy para usuarios de Matlab» . Consultado el 2 de febrero de 2017 .
  19. ^ "notas de la versión de numpy".
  20. ^ McKinney, Wes (2014). "Conceptos básicos de NumPy: matrices y computación vectorizada". Python para análisis de datos (primera edición, tercera edición). O'Reilly. pág. 79. ISBN 978-1-449-31979-3.
  21. ^ Francesc Alted. "numexpr". GitHub . Consultado el 8 de marzo de 2014 .
  22. ^ "Numba" . Consultado el 8 de marzo de 2014 .
  23. ^ Shohei Hido - CuPy: una biblioteca compatible con NumPy para GPU - PyCon 2018, archivado desde el original el 21 de diciembre de 2021 , consultado el 11 de mayo de 2021
  24. ^ Entschev, Peter Andreas (23 de julio de 2019). "Aceleraciones de CuPy con una sola GPU". Medium . Consultado el 11 de mayo de 2021 .
  25. ^ "Documentación F2PY de NumPy". NumPy . Consultado el 18 de abril de 2022 .
  26. ^ Worthey, Guy (3 de enero de 2022). "Un duelo entre Python y Fortran". Guy Worthey . Guy Worthey . Consultado el 18 de abril de 2022 .
  27. ^ Shell, Scott. "Escritura de rutinas rápidas de Fortran para Python" (PDF) . Departamento de Ingeniería de la UCSB . Universidad de California, Santa Bárbara . Consultado el 18 de abril de 2022 .

Lectura adicional

Enlaces externos