Vectorización y Broadcasting en Python
Publicado: 2020-12-01La vectorización y la transmisión son formas de acelerar el tiempo de cómputo y optimizar el uso de la memoria mientras se realizan operaciones matemáticas con Numpy. Estos métodos son cruciales para garantizar que se reduzca la complejidad del tiempo para que los algoritmos no enfrenten cuellos de botella. Este funcionamiento optimizado es necesario para que las aplicaciones sean escalables. Repasaremos ambas técnicas e implementaremos algunos ejemplos.
Al final de este tutorial, tendrá el conocimiento de lo siguiente:
- Cómo Numpy maneja la vectorización
- Diferencias horarias con y sin Vectorización
- Qué es la radiodifusión
- En qué se diferencia la transmisión de la multiplicación matricial habitual
Vectorización
Muchas veces requerimos operaciones matemáticas en matrices, como la multiplicación de matrices. Ahora, una forma no vectorizada sería hacer una multiplicación inteligente de elementos usando un bucle. Implementarlo de esa manera daría como resultado que la misma operación de multiplicación se realice varias veces, lo que sería un desperdicio de recursos informáticos si el tamaño de los datos es demasiado grande. Echemos un vistazo rápido.
Forma no vectorizada:
| Importar al azar a = [random.randint( 1 , 100 ) for _ in range( 10000 )] |
| #Producción: >> 1000 bucles, lo mejor de 3 : 658 µs por bucle |
Forma vectorizada:
| importar numpy como np a = np.array([random.randint( 1 , 100 ) for _ in range( 10000 )]) b = np.array([random.randint( 1 , 100 ) for _ in range( 10000 )]) %tiempoit a*b |
| #Producción: >> 100000 bucles, lo mejor de 3 : 7,25 µs por bucle |
Como vemos, el tiempo transcurrido pasó de 658 microsegundos a tan solo 7,25 microsegundos. Esto se debe a que cuando decimos a = np.array([]) , todas las operaciones son manejadas internamente por numpy. Y cuando hacemos a*b , numpy internamente multiplica la matriz completa a la vez por medio de la vectorización.
Aquí usamos el comando mágico %timeit para cronometrar la ejecución del proceso que puede diferir en su máquina.
Veamos otro ejemplo de productos externos de 2 vectores con dimensiones (nx1) y (1xm). La salida será (nxm).
| tiempo de importación importar numpy matriz de importación a = array.array( 'i' , [random.randint( 1 , 100 ) for _ in range( 100 )]) b = array.array( 'i' , [random.randint( 1 , 100 ) for _ in range( 100 )]) |
| T1 = tiempo.proceso_tiempo() c = numpy.zeros(( 200 , 200 )) para i en el rango (len (a)): para j en el rango (len (b)): c[i][j]= a[i]*b[j] T2 = tiempo.proceso_tiempo() print( f”Tiempo de cómputo = { 1000 *(T2-T1)} ms” ) |
| #Producción: >> Tiempo de cálculo = 6,819299000000001 ms |
Ahora, hagámoslo con Numpy,
| T1 = tiempo.proceso_tiempo() c = numpy.outer(a, b) T2 = tiempo.proceso_tiempo() print( f”Tiempo de cómputo = { 1000 *(T2-T1)} ms” ) |
| #Producción: >> Tiempo de cálculo = 0,2256630000001536 ms |
Como vemos nuevamente, Numpy procesa la misma operación mucho más rápido mediante la vectorización.
Debe leer: Fascinantes aplicaciones de Python en el mundo real
Entonces, hasta ahora, vimos ejemplos en los que se usaron matrices del mismo tamaño. ¿Qué pasa si los tamaños de las matrices son diferentes? Aquí es donde entra en escena otra gran característica de Numpy, la transmisión.
La transmisión es otra extensión de la vectorización donde las matrices no necesitan ser del mismo tamaño para que se realicen operaciones en ellas como suma, resta, multiplicación, etc. Entendamos esto con un ejemplo muy simple de suma de una matriz y un escalar.
| a = np.matriz([ 1 , 1 , 1 , 1 ]) a+ 5 |
| #Producción: matriz ([ 6 , 6 , 6 , 6 ]) |
Como vemos, el escalar 5 se agregó a todos los elementos. Entonces, ¿cómo sucedió?

Para imaginar el proceso, puedes pensar que el escalar 5 se repite 4 veces para hacer una matriz que luego se agrega a la matriz a. Pero tenga en cuenta que Numpy no crea matrices de este tipo que solo ocuparán memoria. Numpy simplemente "transmite" o duplica el escalar 5 hasta 4 lugares para agregarlo a la matriz a.
Tomemos otro ejemplo fácil.
| a = np.unos(( 3 , 3 )) b = np.unos( 3 ) a+b |
| #Producción: >> matriz([[ 2. , 2. , 2. ], [ 2. , 2. , 2. ], [ 2. , 2. , 2. ]]) |
En el ejemplo anterior, la matriz de forma (3,1) se transmitió a (3,3) para que coincida con la matriz a.
Pero, ¿significa esto que cualquier matriz con cualquier dimensión se puede transmitir para que coincida con una matriz con cualquier dimensión?
¡NO!
Reglas de transmisión
Numpy sigue un conjunto de reglas fáciles para asegurarse de que solo se transmitan las matrices que siguen los criterios. Vamos a ver.
La regla de la radiodifusión dice que los 2 arreglos que se van a operar deben tener las mismas dimensiones o si alguno de ellos es 1.
Veamos que esto está en acción.
Ejemplo 1:
Considere las siguientes matrices de dimensiones:
a = 3x4x7
b = 3x4x1
Aquí, la última dimensión de b se transmitirá para que coincida con la de a a 7.
Por lo tanto, resultado = 3 x 4 x 7
Ejemplo 2:
a = 3x4x7 _
segundo = 4
Ahora, el número de dimensiones de a y b son desiguales. En tales casos, la matriz con menor número de dimensiones se rellenará con 1.
Entonces, aquí, la primera y la última dimensión de b son 1, por lo que se transmitirán para que coincidan con las de a en 3 y 7.
Por lo tanto, resultado = 3 x 4 x 7.
Leer: Tutorial de Python
Ejemplo 3:
a = 3x4x1x5 _
b = 3x1x7x1
Aquí, nuevamente, la segunda y última dimensión de b se transmitirá para que coincida con la de a en 4 y 5. Además, la tercera dimensión de a se transmitirá para que coincida con la de b en 7.
Por lo tanto, resultado = 3 x 4 x 7 x 5
Ahora veamos cuando falla la condición:
Ejemplo 4:
a = 3x4x7x5 _
b = 3x3x7x4
Aquí, la segunda y cuarta dimensión de b no coinciden con a y tampoco son 1. En este caso, Python arrojará un error de valor:
| ValueError: los operandos no se pudieron transmitir junto con las formas ( 3 , 4 , 7 , 5 ) ( 3 , 3 , 7 , 4 ) |
Ejemplo 5:
a = 3x4x1x5
b = 3x2x3
Resultado: Error de valor
Aquí también, la segunda dimensión no coincide y tampoco es 1 para ninguno de los dos.
Antes de que te vayas
La vectorización y la transmisión, ambas, son métodos con los que Numpy optimiza y hace más eficiente su procesamiento. Estos conceptos deben tenerse en cuenta especialmente cuando se trata de matrices y arreglos n-dimensionales, que son muy comunes en datos de imágenes y redes neuronales.
Si tiene curiosidad por aprender sobre python, ciencia de datos, consulte el Diploma PG en ciencia de datos de IIIT-B y upGrad, creado para profesionales que trabajan y ofrece más de 10 estudios de casos y proyectos, talleres prácticos, tutoría con expertos de la industria, 1 a 1 con mentores de la industria, más de 400 horas de aprendizaje y asistencia laboral con las mejores empresas.
¿Qué es la vectorización en Python?
Numpy es un paquete de Python que proporciona varias funciones matemáticas estándar que permiten operaciones rápidas en grandes conjuntos de datos sin necesidad de bucles, incluida la vectorización. La vectorización se utiliza para acelerar los programas de Python sin el uso de bucles. El uso de dicho método puede ayudar a reducir la cantidad de tiempo que tarda el código en ejecutarse. Hay varias operaciones que se llevan a cabo en vectores, como el producto punto de vectores, también conocido como producto escalar porque produce una sola salida, productos externos, lo que da como resultado una matriz cuadrada de dimensión igual a la longitud x longitud de la vectores, multiplicación por elementos, que produce elementos con los mismos índices.
¿Qué es la transmisión en Python?
La palabra transmisión se refiere a cómo Numpy administra matrices con diferentes dimensiones durante las operaciones aritméticas que resultan en restricciones específicas; la matriz más pequeña se transmite a través de la matriz enorme para que sus formas sean consistentes. La transmisión le permite vectorizar operaciones de matriz de modo que el bucle se realice en C en lugar de Python, como lo hace Numpy. Logra esto sin crear copias innecesarias de datos, lo que resulta en implementaciones de algoritmos eficientes. En ciertas situaciones, la transmisión es una idea negativa, ya que genera un consumo de memoria derrochador, lo que ralentiza el procesamiento.
¿Cuáles son los usos de NumPy en Python?
NumPy o Numerical Python es una biblioteca de Python gratuita y de código abierto utilizada por casi todas las ramas de investigación e ingeniería. La biblioteca NumPy incluye matrices multidimensionales y estructuras de datos matriciales y ofrece métodos para operar de manera eficiente en una matriz, un objeto de matriz n-dimensional homogéneo. Los usuarios pueden usar NumPy para ejecutar una amplia gama de operaciones matemáticas en matrices. Mejora Python con estructuras de datos sólidas que proporcionan cálculos eficientes con arreglos y matrices, así como una biblioteca masiva de funciones matemáticas de alto nivel que funcionan en estos arreglos y matrices.
