Ir al contenido
wannacode

El arreglo de NumPy

En resumen: Un arreglo de NumPy (ndarray) contiene números de un solo tipo (dtype) con una forma, y calcula con ellos mucho más rápido que una lista de Python.

Problema

«Súmale el IVA a cada precio»

La tienda tiene 25 productos. El gerente quiere los precios con IVA: cada precio por 1,2. Después quiere un año de ventas por día: 25 productos durante 365 días, es decir, 9125 números.

Hasta ahora los números en Python vivían en una lista. Pero una lista no hace cuentas:

Pythondatos: las tablas de la tienda

* 2 no duplica los precios, repite la lista dos veces. * 1.2 es un error. Queda un bucle for para cada cálculo, y con 9125 números, luego con un millón, el código se vuelve largo y lento.

La idea

Un arreglo: un bloque de números

Una lista es una colección de objetos separados. Cada una de sus casillas guarda una dirección, y el número mismo está en otro lugar de la memoria, con su propio «envoltorio» de Python. Por eso una lista puede guardar cualquier cosa: un número, texto, otra lista.

El análisis de datos no necesita eso. Necesita muchos números del mismo tipo. NumPy es la biblioteca para esto, y su núcleo es el arreglo: los números están uno al lado del otro en un bloque de memoria, todos del mismo tipo. Aquí tienes un millón de precios como lista y como arreglo:

Pythondatos: las tablas de la tienda

La lista ocupa 20,2 MB y el arreglo 8,0 MB: 8 bytes por precio y nada más. El sandbox es de 32 bits. En una computadora normal de 64 bits las direcciones y los envoltorios son más grandes y la lista crece hasta unos 32 MB, mientras que el arreglo se queda en 8 MB.

Un bloque de números del mismo tipo también se recorre más rápido: NumPy pasa por encima con código C ya hecho, sin preguntar el tipo de cada número. Aquí está el IVA sobre un millón de precios:

Pythondatos: las tablas de la tienda

array * 1.2 multiplica todos los precios de una vez. En el sandbox el arreglo es varias veces más rápido que el bucle. En una computadora normal la diferencia es de decenas de veces. El tiempo exacto depende de la máquina, por eso el código solo dice cuál es más rápido.

Más precisamente, para curiosos

import numpy as np es la costumbre de todos, como pd para pandas. pandas mismo está construido sobre NumPy: una columna de una tabla guarda sus números en un arreglo. Así que lo que aprendes aquí también vale para las tablas.

La idea

Un arreglo desde la tabla: dtype

Los precios ya están en products.csv. to_numpy() toma una columna de la tabla como arreglo. Cada arreglo conoce el tipo de sus números: es el dtype.

Pythondatos: las tablas de la tienda

prices[:5] da los cinco primeros, como con una lista. Un arreglo se imprime sin comas: [1.2 1.9 0.8 2.5 1.6].

  • float64: números decimales, de 8 bytes cada uno (64 bits). Los precios son así.
  • int64: números enteros, también de 8 bytes cada uno. El stock es así.

Míralo

Cuando se mezclan los tipos

Hay un solo tipo para todo el arreglo. ¿Qué pasa si metes cosas distintas?

Pythondatos: las tablas de la tienda
  • Enteros y decimales: todos pasan a decimales. 40 pasa a 40.0 sin pérdida, mientras que al revés se cortaría el 1.5.
  • Un solo trozo de texto: todo pasa a texto. <U32 significa una cadena de hasta 32 caracteres. Los números ya no son números.
1. ¿Qué da np.array([1.2, 1.9, '0.8']) * 2?
Más precisamente, para curiosos

Si escribes np.array([40, 25, 60]) en el sandbox, el tipo es int32, no int64. El entero por defecto sigue a la máquina, y el sandbox es de 32 bits. En tu computadora es int64. Las columnas leídas con pandas son int64 también aquí. Para cantidades en una tienda bastan los dos tipos: int32 admite números hasta unos 2100 millones.

La idea

La forma: shape y ndim

Los precios son una fila de números. Las ventas por semana son una tabla: una fila para cada producto, una columna para cada semana. Un arreglo puede ser las dos cosas.

  • shape es la forma: cuántos números hay en cada dirección.
  • ndim es el número de direcciones (dimensiones).
Pythondatos: las tablas de la tienda

Los precios tienen la forma (25,): una dimensión con 25 números. La coma está ahí porque una forma siempre es un par, una tripleta y así sucesivamente (una tupla), incluso con un solo número dentro. La tabla es (3, 4): 3 filas (los productos) y 4 columnas (las semanas). Primero las filas, luego las columnas, como con shape en pandas.

Pruébalo

Productos y semanas

qty tiene las unidades por producto (filas) y por semana (columnas). Pon el número de productos en n_products y el número de semanas en n_weeks, tomados de la forma del arreglo.

Pythondatos: las tablas de la tienda

La idea

Arreglos ya hechos: arange y zeros

A menudo un arreglo no viene de un archivo, lo haces tú:

  • np.arange(inicio, fin) da números consecutivos, como range. El final no se incluye.
  • np.zeros(forma) da un arreglo de ceros. Es útil para una tabla que vas a rellenar. La forma de una tabla es un par: np.zeros((filas, columnas)), con doble paréntesis.
Pythondatos: las tablas de la tienda

Los días van del 1 al 365, así que el final es 366. La tabla para un año de ventas es (25, 365): 9125 ceros de tipo float64, listos para los números.

Ejercicio

La lista de precios y el año

Crea days con los días del 1 al 365, y sales: una tabla de ceros con una fila para cada uno de los 25 productos y una columna para cada día.

Pythondatos: las tablas de la tienda

Pon los precios y el stock en una tabla de arreglo con dos filas: en la primera los precios, en la segunda el stock. Pon el tipo de la tabla en kind.

Pythondatos: las tablas de la tienda

Test

Ponte a prueba

1. ¿Por qué un arreglo de un millón de precios ocupa menos memoria que una lista con los mismos precios?
2. ¿Cuál es el dtype de np.array([40, 25, 1.5])?
3. Las ventas de 25 productos durante 7 días están en un arreglo con una fila por producto. ¿Qué es sales.shape?
4. ¿Qué días da np.arange(1, 8)?

Creado por Ivo Gergov como parte de la campaña de Evo Tech por una educación accesible en programación ·