¿Cuáles son las ventajas de NumPy sobre las listas regulares de Python?


466

¿Cuáles son las ventajas de NumPy sobre las listas regulares de Python?

Tengo aproximadamente 100 series de mercados financieros, y voy a crear una matriz de cubos de 100x100x100 = 1 millón de celdas. Regresaré (3 variables) cada x con cada y y z, para llenar la matriz con errores estándar.

He oído que para "matrices grandes" debería usar NumPy en lugar de las listas de Python, por razones de rendimiento y escalabilidad. La cosa es que conozco las listas de Python y parecen funcionar para mí.

¿Cuáles serán los beneficios si me mudo a NumPy?

¿Qué pasa si tuviera 1000 series (es decir, mil millones de celdas de coma flotante en el cubo)?

Respuestas:


727

Las matrices de NumPy son más compactas que las listas de Python: una lista de listas como usted describe, en Python, tomaría al menos 20 MB más o menos, mientras que una matriz NumPy 3D con flotadores de precisión simple en las celdas cabría en 4 MB. El acceso en elementos de lectura y escritura también es más rápido con NumPy.

Tal vez no le importe tanto por solo un millón de celdas, pero definitivamente lo haría por mil millones de celdas: ninguno de los enfoques encajaría en una arquitectura de 32 bits, pero con las construcciones de 64 bits, NumPy se saldría con 4 GB más o menos , Python solo necesitaría al menos unos 12 GB (muchos punteros que duplican su tamaño), ¡una pieza de hardware mucho más costosa!

La diferencia se debe principalmente a la "indirecta": una lista de Python es una matriz de punteros a objetos de Python, al menos 4 bytes por puntero más 16 bytes incluso para el objeto Python más pequeño (4 para el puntero tipo, 4 para el recuento de referencias, 4 por valor, y los asignadores de memoria se redondean hasta 16). Una matriz NumPy es una matriz de valores uniformes: los números de precisión simple requieren 4 bytes cada uno, los de precisión doble, 8 bytes. Menos flexible, ¡pero paga sustancialmente por la flexibilidad de las listas estándar de Python!


He estado tratando de usar "sys.getsizeof ()" para comparar el tamaño de las listas de Python y las matrices NumPy con el mismo número de elementos y no parece indicar que las matrices NumPy fueran mucho más pequeñas. ¿Es este el caso o sys.getsizeof () tiene problemas para determinar qué tan grande es una matriz NumPy?
Jack Simpson

3
@JackSimpson getsizeofno es confiable. La documentación establece claramente que: Solo se tiene en cuenta el consumo de memoria directamente atribuido al objeto, no el consumo de memoria de los objetos a los que se refiere. Esto significa que si ha anidado Python List, el tamaño de los elementos no se tiene en cuenta.
Bakuriu el

44
getsizeofen una lista solo le dice cuánta RAM consume el objeto de la lista y la RAM consumida por los punteros en su matriz de datos, no le dice cuánta RAM consumen los objetos a los que se refieren esos punteros.
PM 2Ring

@AlexMartelli, ¿podría decirme dónde obtiene estos números?
lmiguelvargasf

Solo un aviso, su estimación del tamaño de la lista de listas de Python equivalente está desactivada. Array El 4 GB numpy de C floats (4 bytes) se traduciría en algo más cerca de 32 GB valor de lists y Python floats (que en realidad son C doubles), no 12 GB; cada uno floaten Python de 64 bits ocupa ~ 24 bytes (suponiendo que no haya pérdidas de alineación en el asignador), más otros 8 bytes en el listpara contener la referencia (y eso ignora la sobreasignación y los encabezados de objeto para los listpropios s, lo que podría agregar otro GB dependiendo de exactamente cuánto ocurre la sobreasignación).
ShadowRanger

232

NumPy no solo es más eficiente; También es más conveniente. Obtiene muchas operaciones de vectores y matrices de forma gratuita, lo que a veces le permite a uno evitar trabajos innecesarios. Y también se implementan de manera eficiente.

Por ejemplo, podría leer su cubo directamente desde un archivo en una matriz:

x = numpy.fromfile(file=open("data"), dtype=float).reshape((100, 100, 100))

Suma a lo largo de la segunda dimensión:

s = x.sum(axis=1)

Encuentra qué celdas están por encima de un umbral:

(x > 0.5).nonzero()

Elimine cada segmento indexado uniforme a lo largo de la tercera dimensión:

x[:, :, ::2]

Además, muchas bibliotecas útiles funcionan con matrices NumPy. Por ejemplo, análisis estadísticos y bibliotecas de visualización.

Incluso si no tiene problemas de rendimiento, vale la pena aprender NumPy.


Gracias: ha proporcionado otra buena razón en su tercer ejemplo, ya que, de hecho, buscaré en la matriz celdas por encima del umbral. Además, estaba cargando desde sqlLite. El enfoque de archivo será mucho más eficiente.
Thomas Browne

112

Alex mencionó la eficiencia de la memoria, y Roberto menciona la conveniencia, y estos son buenos puntos. Para algunas ideas más, mencionaré velocidad y funcionalidad .

Funcionalidad: obtienes mucho con NumPy, FFT, convoluciones, búsqueda rápida, estadísticas básicas, álgebra lineal, histogramas, etc. Y realmente, ¿quién puede vivir sin FFT?

Velocidad: Aquí hay una prueba para hacer una suma sobre una lista y una matriz NumPy, que muestra que la suma en la matriz NumPy es 10 veces más rápida (en esta prueba, el kilometraje puede variar).

from numpy import arange
from timeit import Timer

Nelements = 10000
Ntimeits = 10000

x = arange(Nelements)
y = range(Nelements)

t_numpy = Timer("x.sum()", "from __main__ import x")
t_list = Timer("sum(y)", "from __main__ import y")
print("numpy: %.3e" % (t_numpy.timeit(Ntimeits)/Ntimeits,))
print("list:  %.3e" % (t_list.timeit(Ntimeits)/Ntimeits,))

que en mis sistemas (mientras estoy ejecutando una copia de seguridad) da:

numpy: 3.004e-05
list:  5.363e-04

44

Aquí hay una buena respuesta de las preguntas frecuentes en el sitio web scipy.org :

¿Qué ventajas ofrecen las matrices NumPy sobre las listas de Python (anidadas)?

Las listas de Python son contenedores eficientes de uso general. Admiten inserción, eliminación, anexos y concatenación (bastante) eficientes, y las comprensiones de la lista de Python los hacen fáciles de construir y manipular. Sin embargo, tienen ciertas limitaciones: no admiten operaciones "vectorizadas" como la suma y multiplicación por elementos, y el hecho de que pueden contener objetos de diferentes tipos significa que Python debe almacenar información de tipo para cada elemento y debe ejecutar código de envío de tipo cuando se opera en cada elemento. Esto también significa que muy pocas operaciones de lista pueden llevarse a cabo mediante bucles C eficientes: cada iteración requeriría verificaciones de tipo y otra contabilidad de Python API.


9

Todos han resaltado casi todas las diferencias principales entre la matriz numpy y la lista de python, solo las explicaré aquí:

  1. Las matrices Numpy tienen un tamaño fijo en la creación, a diferencia de las listas de Python (que pueden crecer dinámicamente). Cambiar el tamaño de ndarray creará una nueva matriz y eliminará el original.

  2. Se requiere que todos los elementos en una matriz de Numpy sean del mismo tipo de datos (también podemos tener el tipo heterogéneo pero eso no le permitirá operaciones matemáticas) y, por lo tanto, tendrá el mismo tamaño en la memoria

  3. Las matrices de Numpy se facilitan avances matemáticos y otros tipos de operaciones en grandes cantidades de datos. Típicamente, tales operaciones se ejecutan de manera más eficiente y con menos código del que es posible usando las secuencias de construcción de pitones

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.