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

511

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

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

Escuché que para "matrices grandes" debería usar NumPy en lugar de 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 cambio a NumPy?

¿Qué pasaría si tuviera 1000 series (es decir, mil millones de celdas de punto flotante en el cubo)?

0
778

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 a los elementos de lectura y escritura también es más rápido con NumPy.

Tal vez no le importe mucho solo un millón de celdas, pero definitivamente lo haría con mil millones de celdas; ninguno de los enfoques encajaría en una arquitectura de 32 bits, pero con compilaciones de 64 bits, NumPy se saldría con la suya 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 Python, al menos 4 bytes por puntero más 16 bytes incluso para el objeto Python más pequeño (4 para puntero de tipo, 4 para recuento de referencias, 4 por valor - y los asignadores de memoria se redondea a 16). Una matriz NumPy es una matriz de valores uniformes: los números de precisión simple toman 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!

8
  • 1
    He estado intentando 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? 8 de junio de 2016 a las 12:41
  • 6
    @JackSimpson getsizeofno es confiable. La documentación establece claramente que: Solo se contabiliza el consumo de memoria atribuido directamente al objeto, no el consumo de memoria de los objetos a los que se refiere. Esto significa que si tiene listas de Python anidadas, el tamaño de los elementos no se tiene en cuenta.
    Bakuriu
    9 de agosto de 2016 a las 19:40
  • 5
    getsizeof en 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. 10/10/2016 a las 12:38
  • @AlexMartelli, ¿podría decirme dónde está obteniendo estos números? 6 de mayo de 2017 a las 18:49
  • 3
    Solo un aviso, su estimación sobre el tamaño de la lista de listas de listas de Python equivalente está desactivada. La matriz numérica de 4 GB de C floats (4 bytes) se traduciría en algo más cercano a 32 GB de listsy 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ánta sobreasignación ocurre). 8 de noviembre de 2018 a las 2:18
247

NumPy no solo es más eficiente; también es más conveniente. Obtiene una gran cantidad de operaciones vectoriales y matriciales de forma gratuita, lo que a veces le permite evitar trabajos innecesarios. Y también se implementan de manera eficiente.

Por ejemplo, puede 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)

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

(x > 0.5).nonzero()

Elimine todos los cortes con índices pares a lo largo de la tercera dimensión:

x[:, :, ::2]

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

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

1
  • 2
    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. 14/06/09 a las 23:54
116

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

Funcionalidad: Obtienes mucho integrado 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
0
47

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)?

Python’s lists are efficient general-purpose containers. They support (fairly) efficient insertion, deletion, appending, and concatenation, and Python’s list comprehensions make them easy to construct and manipulate. However, they have certain limitations: they don’t support “vectorized” operations like elementwise addition and multiplication, and the fact that they can contain objects of differing types mean that Python must store type information for every element, and must execute type dispatching code when operating on each element. This also means that very few list operations can be carried out by efficient C loops – each iteration would require type checks and other Python API bookkeeping.

14

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

  1. Las matrices Numpy tienen un tamaño fijo en el momento de 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á la original.

  2. Todos los elementos en una matriz Numpy deben ser 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án el mismo tamaño en la memoria.

  3. Numpy arrays se facilitan avances matemáticos y otros tipos de operaciones en grandes cantidades de datos. Por lo general, estas operaciones se ejecutan de manera más eficiente y con menos código de lo que es posible usando las secuencias de compilación de pitones.