You don't have access to this class

Keep learning! Join and start boosting your career

Aprovecha el precio especial y haz tu profesión a prueba de IA

Antes: $249

Currency
$209
Suscríbete

Termina en:

0 Días
3 Hrs
5 Min
36 Seg

Broadcasting y Operaciones Lógicas en NumPy

6/32
Resources

What is broadcasting in NumPy?

Broadcasting is a powerful feature in NumPy that allows you to perform arithmetic operations on arrays of different sizes and shapes efficiently. Instead of iterating over each element of the arrays to perform the operations, NumPy automatically extends smaller arrays to match the dimensions of larger arrays, without duplicating data. This not only optimizes memory usage, but also significantly speeds up operations.

Broadcasting allows operations between arrays of different dimensions to be performed as if all arrays had the same shape. NumPy extends smaller arrays to the shape of the larger one implicitly, facilitating operations without the need to copy data.

Broadcasting Applications.

  • Discounting Application: Suppose we have an array representing the prices of several products and another array with a percentage discount that applies to all products. With broadcasting, we can apply the discount without the need for an explicit loop.

    
    import numpy as np prices = np.array([100, 200, 300]) discount = np.array([0.9]) discounted_prices = prices * discount print(discounted_prices) # Output: [ 90. 180. 270.]
  • Operations with Multidimensional Arrays: We can perform elementary operations between arrays of different dimensions.

    
    a = np.array([[[0.0, 0.0, 0.0, 0.0], [10.0, 10.0, 10.0, 10.0], [20.0, 20.0, 20 . 0], [30.0, 30.0, 30.0]]]) b = np.array([1.0, 2.0, 2.0, 3.0]) result = a + b print(result)# Output:# [[ 1.2. 3.]# [11. 12. 13.]# [21. 22. 23.]# [31. 32. 33. 33.]]]

Importance of Broadcasting

Broadcasting is crucial because it allows writing more concise and readable code, avoiding explicit loops and taking advantage of NumPy's internal optimizations to perform operations quickly and efficiently. This is especially useful in data analysis and machine learning, where large volumes of data are handled and fast computations are required.

Broadcasting Rules

For broadcasting to work, array dimensions must meet certain rules:

  1. Comparison from the Last Dimension: Dimensions are compared from the last to the first.
  2. Compatible Dimensions: Two dimensions are compatible if they are equal or if one of them is 1.

Examples:

  • Scalar and 1D Array:

    
    a = np.array([1, 2, 3]) b = 2result = a * b print(result) # Output: [2 4 6].
  • 1D Array and 2D Array:

    
    a = np.array([[[1, 2, 3], [4, 5, 6], [7, 8, 9]]]) b = np.array([1, 0, 1]) result = a * b print(result)# Output:# [[1 0 3]# [4 0 6]# [7 0 9]]
  • 2D Array and 3D Array:

    
    a = np.array([[[[1], [2], [3]], [[4], [5], [6]]]]) b = np.array([1, 2, 3]) result = a * b print(result)# Output:# [[[ 1 23]# [ 2 46]# [ 3 69]]# #[[ 4 8 12]# [ 5 10 15]# [ 6 12 18]]]]

Broadcasting in NumPy is an essential technique for performing arithmetic operations efficiently on arrays of different sizes and shapes. Understanding and applying broadcasting rules allows you to write cleaner and more optimized code, crucial for data analysis and machine learning tasks.

Explore these features and discover how broadcasting can improve the efficiency of your Python calculations.

Contributions 22

Questions 3

Sort by:

Want to see more contributions, questions and answers from the community?

Solo para anotar que en el último ejercicio de split, esta usando la variable "array"(que seguro fue declarado líneas arriba) y no "array\_c", estoy seguro que todos lo notarán pero lo comento por si alguien no.
📝 **Ejemplos de broadcasting con numpy** **Ejemplo #1**: Tenemos un conjunto de datos que representa la medición de temperatura de 7 días en 3 ciudades diferentes (array de 3 x 7). Sin embargo las mediciones tienen un margen de error, y se nos da un array unidimensional con los valores de corrección para cada día de la semana (array de 1 x 7). Para acer la corrección en la medición de temperatura, en lugar de duplicar el array de corrección para cada ciudad (fila), aplicamos broadcasting: ```python import numpy as np # Temperaturas (3 ciudades, 7 días) temperaturas = np.array([ [30, 32, 31, 29, 28, 27, 26], [25, 24, 22, 23, 26, 27, 28], [20, 21, 19, 18, 17, 16, 15] ]) # Corrección (1 valor por día) correccion = np.array([1, -1, 0.5, -0.5, 0, 1, -1]) # Aplicar la corrección usando broadcasting temperaturas_corregidas = temperaturas + correccion print("Temperaturas originales:\n", temperaturas) print("\nCorrección aplicada:\n", correccion) print("\nTemperaturas corregidas:\n", temperaturas_corregidas) ``` Resultado: ```txt [[30 32 31 29 28 27 26] [25 24 22 23 26 27 28] [20 21 19 18 17 16 15]] Corrección aplicada: [ 1. -1. 0.5 -0.5 0. 1. -1. ] Temperaturas corregidas: [[31. 31. 31.5 28.5 28. 28. 25. ] [26. 23. 22.5 22.5 26. 28. 27. ] [21. 20. 19.5 17.5 17. 17. 14. ]] ``` Internamente `numpy` expande verticalmente el array de correcciones para que tenga la misma forma (3 x 7) que el array con los datos de las temperaturas por ciudad, visualmente sería algo así: ![](https://res.cloudinary.com/dmwsbri4c/image/upload/v1723849647/Numpy_broadcasting_qi8zzw.jpg) **Ejemplo #2:** Tenemos una matriz 3x3 que representa los valores de ventas de tres productos en tres diferentes tiendas, y un vector 3x1 que contiene un bono de ventas que se aplica por tienda. El broadcasting permite sumar este bono de manera eficiente a cada fila de la matriz. ```python import numpy as np # Ventas de productos en diferentes tiendas ventas = np.array([ [100, 200, 300], [400, 500, 600], [700, 800, 900] ]) # Bono de ventas por tienda bono = np.array([ [10], [20], [30] ]) ventas_actualizadas = ventas + bono print("Ventas actualizadas:\n", ventas_actualizadas) ``` Resultado: ```txt Ventas actualizadas: [[110 210 310] [420 520 620] [730 830 930]] ``` En este ejemplo, numpy expande el array de forma horizontal (agregando las columnas "faltantes"), visualmente lo que ocurre es lo siguiente: ![](https://res.cloudinary.com/dmwsbri4c/image/upload/v1723849647/Numpy_broadcasting_2_eabw1w.jpg)
![](https://static.platzi.com/media/user_upload/image-e092aa92-dc80-4bdd-82b9-150cf79630de.jpg) # Resumen * **Broadcasting**: Permite realizar operaciones en arrays de diferentes formas sin necesidad de duplicar datos. * **Operaciones Lógicas**: Permiten realizar comparaciones en arrays y crear máscaras booleanas. * **Combinación**: Broadcasting y operaciones lógicas se pueden combinar para realizar manipulaciones avanzadas en arrays.
Mientras practicaba descubri este comando que les puede ser util. Ya vimos en clases pasadas que para generar una matriz de números aleatorios NxN era tan fácil como: `Matrix = np.random.randint(1,10,size=(3,3))` Estaba buscando la manera de hacer lo mismo, pero en lugar de números aleatorios con los números ordenados del 1 al 9. Intente utilizar la misma sintaxis que usamos con el `randint`, pero no funciono, entonces encontre esta forma: `Matrix = np.arange(1, 10).reshape(3, 3)` `Output:` `[[1 2 3]` ` [4 5 6]` ` [7 8 9]]` De esta forma se generara un arreglo de números ordenados en el rango indicado, y luego se reordenara con las dimensiones especificadas en el `reshape`.
```python # Acceder al primer subarray subarray_1 = split_array[0] # Acceder al segundo subarray subarray_2 = split_array[1] print(subarray_1) # Salida: [0 1 2 3 4] print(subarray_2) # Salida: [5 6 7 8 9] ```De esa manera accedemos a los subarray creados.
El concepto de **broadcasting** en NumPy es un mecanismo que permite realizar operaciones aritméticas en matrices (arrays) de diferentes formas y tamaños sin necesidad de replicar explícitamente los datos. En lugar de crear una copia completa de un array para que coincida en dimensiones con otro, NumPy ajusta automáticamente las dimensiones para hacer posible la operación.
El ejercicio que estuve probando fue el tener una condicional que se aplique a los precios usando np.where: ```js prices = np.arange(100, 500, step=100) discount = np.random.rand(1, 2).round(2) discount1, discount2 = np.sort(discount.flatten()) discount_prices = np.where(prices > 250, prices * (1 - discount2), prices * (1- discount1)) print(f'Prices: {prices}') print(f'Minimum discount: {discount1}, Maximum discount: {discount2}') print(f'Prices with discount: {discount_prices}') ```prices = np.arange(100, 500, step=100)discount = np.random.rand(1, 2).round(2)discount1, discount2 = np.sort(discount.flatten())discount\_prices = np.where(prices > 250, prices \* (1 - discount2), prices \* (1- discount1)) print(f'Prices: {prices}')print(f'Minimum discount: {discount1}, Maximum discount: {discount2}')print(f'Prices with discount: {discount\_prices}')
Hola me aparece este error en la funciòn concatenar y no sè porquè.#concatener...array\_a = np.array(\[1,2,3])array\_b = np.array(\[4,5,6])print(array\_a)concatenated\_a = np.concatenate((array\_a,array\_b))print(concatenated\_a)![](<Captura de pantalla 2025-04-02 a la(s) 3.38.08 p.m.>)```js #concatener... array_a = np.array([1,2,3]) array_b = np.array([4,5,6]) print(array_a) concatenated_a = np.concatenate((array_a,array_b)) print(concatenated_a) ``` 1 2 3] \--------------------------------------------------------------------------- TypeError Traceback (most recent call last) [\<ipython-input-102-ae8ab9315f10>](https://localhost:8080/#) in \<cell line: 0>() 3 array\_b = np.array(\[4,5,6]) 4 print(array\_a) \----> 5 concatenated\_a = np.concatenate((array\_a,array\_b)) 6 print(concatenated\_a) 7 TypeError: 'numpy.ndarray' object is not callable ![]()
Ejemplo: Normalización de datos `# Datos de ejemplo ` `datos = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) ` `# Calcular media y desviación estándar ` `media = datos.mean(axis=0) ` `std = datos.std(axis=0) ` `# Normalizar datos ` `datos_normalizados = (datos - media) / std ` `print(media) ` `print(std) ` `print(datos_normalizados) ` `[4. 5. 6.] ` `[2.44948974 2.44948974 2.44948974] ` `[[-1.22474487 -1.22474487 -1.22474487] ` ` [ 0. 0. 0. ]` ` [ 1.22474487 1.22474487 1.22474487]]`
esto esta bien locochon, el broadcasting es para hacer operaciones elemento a elemento con matricez, sinembargo si hago una multiplicacion de una matriz 3,4 con un vector 4,0 es como si hiciera multiplicacion elemento a elemento rotando el arreglo 4,0 por las filas de la matriz 3,4. si quiero hacer lo mismo pero rotando por las columnas tengo que hacer un reshape para poder hacer un vector columna 3,1 , transponer un vector 3,0 que seria la forma original del numpy array es imposible. pero si al reshape le doy una dimension mas y hago .reshape(-1,1,1) y multiplico el resultado es un tensor 3,4,3 donde a cada matriz de la tercera dimencion se le multiplico cada elemento por uno de los escalares del vector discount
#### **1. BROADCASTING** **Descripción:** El broadcasting en Numpy permite realizar operaciones aritméticas entre arreglos de diferentes dimensiones. Los arreglos más pequeños se "amplían" automáticamente para coincidir con la forma de los más grandes durante las operaciones, sin copiar datos explícitamente. **Ejemplos:** **Código:** prices = np.array(\[100, 200, 300]) discount = np.array(\[0.9]) discount\_prices = prices \* discount print(discount\_prices) *  **Resultado:** \[90. 180. 270.]  * **Explicación:** El arreglo discount (con un solo valor) se expande para coincidir con la forma de prices. Se realiza la multiplicación elemento por elemento. **Código:** prices = np.random.randint(100, 500, size=(3, 3)) discount = np.array(\[10, 20, 30]) discount\_prices = prices + discount print(prices) print(discount\_prices)  **Resultado:** prices:  \[\[105 187 338]  \[365 341 249]  \[350 310 347]] discount\_prices:  \[\[115 207 368]  \[375 361 279]  \[360 330 377]] *  **Explicación:** Aquí, el arreglo discount (1D) se expande a lo largo de las filas del arreglo 2D prices. Cada columna se suma elemento por elemento al valor correspondiente de discount. #### **2. OPERACIONES LÓGICAS** **Descripción:** Las operaciones lógicas en Numpy (all, any) evalúan condiciones sobre los elementos de un arreglo. Estas son útiles para verificar condiciones. **Ejemplos:** **Código:** array = np.array(\[1, 2, 3, 4, 5]) print(np.all(array > 9)) *  **Resultado:** False **Explicación:** La función np.all verifica si todos los elementos cumplen la condición (> 9). Como ningún elemento la cumple, devuelve False. **Código:** print(np.any(array > 4)) *  **Resultado:** True **Explicación:** La función np.any verifica si algún elemento cumple la condición (> 4). Como 5 la cumple, el resultado es True. #### **3. CONCATENATE & STACKING** **Descripción:** * Concatenate fusiona arreglos a lo largo de un eje existente. * Stacking combina arreglos a lo largo de un nuevo eje. **Ejemplos:** **CONCATENATE:** array\_a = np.array(\[1, 2, 3]) array\_b = np.array(\[4, 5, 6]) concatenated\_a = np.concatenate((array\_a, array\_a)) concatenated\_ab = np.concatenate((array\_a, array\_b)) print(concatenated\_a) print(concatenated\_ab)  **Resultado:** \[1 2 3 1 2 3] \[1 2 3 4 5 6] *  **Explicación:** Los arreglos se concatenan a lo largo del eje predeterminado (eje 0). **STACKING:** stacked\_v = np.vstack((array\_a, array\_b)) print(stacked\_v)  **Resultado:** \[\[1 2 3]  \[4 5 6]] *  **Explicación:** vstack apila arreglos verticalmente (por filas). stacked\_h = np.hstack((array\_a, array\_b)) print(stacked\_h) *  **Resultado:** \[1 2 3 4 5 6]  * **Explicación:** hstack apila arreglos horizontalmente (por columnas). #### **4. SPLIT** **Descripción:** La función split divide un arreglo en múltiples sub-arreglos. **Ejemplos:** **Código:** array = np.arange(1, 10) split\_array = np.split(array, 3) print(array) print(split\_array)  **Resultado:** array: \[1 2 3 4 5 6 7 8 9] split\_array: \[array(\[1, 2, 3]), array(\[4, 5, 6]), array(\[7, 8, 9])] *  **Explicación:** El arreglo se divide en 3 partes iguales. Cada parte es un nuevo sub-arreglo.
[FelixUcTech/Py-Data-Analysis](https://github.com/FelixUcTech/Py-Data-Analysis) des dejo mi repo, espero les sirva está en la carpeta A01, todas mis notas.
Lo hice con array\_c para obtener la misma salida que hace la profe porque me lanzaba error: ![](https://static.platzi.com/media/user_upload/image-5196e78d-f2b1-4443-99b3-5c24efd0fa46.jpg)
Ojo: minuto 11:30
### **Key Differences**: 1. `concatenate`: * Joins arrays along an existing axis. * The number of dimensions stays the same. 2. `stack`: * Joins arrays along a new axis. * Increases the number of dimensions.
Para que el **broadcasting** sea posible, al menos una de las dimensiones (filas o columnas) debe ser igual a **1** o debe coincidir con la otra. Esto es lo que permite a NumPy **expandir** automáticamente el array más pequeño para que las operaciones puedan llevarse a cabo sin problemas. Por ejemplo, si tienes un array de forma (3, 2) y otro de forma (3, 1), NumPy puede "extender" el array más pequeño (que tiene una columna) para que tenga 2 columnas y coincida con el otro
```js import numpy as np # Definir las cantidades, plazos y tasas de los bancos cantidades = np.array([20000, 30000, 60000]) # Tres cantidades plazos = np.array([3, 6, 12]) # Tres plazos diferentes banco_1 = np.array([0.14, 0.04, 0.02]) # Tasas del banco 1 banco_2 = np.array([0.17, 0.07, 0.01]) # Tasas del banco 2 banco_3 = np.array([0.15, 0.06, 0.03]) # Tasas del banco 3 # Agrupar las tasas de los bancos en un solo array bancos = np.array([banco_1, banco_2, banco_3]) # Dimensión (3 bancos, 3 plazos) # Aplicar broadcasting para calcular el préstamo total # Asegurarse de que las dimensiones sean compatibles para el broadcasting prestamo = cantidades[:, np.newaxis, np.newaxis] * (1 + bancos[np.newaxis, :, :]) ** plazos[np.newaxis, np.newaxis, :] # Mostrar el resultado de los préstamos calculados para cada combinación print(prestamo) ```Resultado \[\[\[29630.88 25306.38036992 25364.83589125] \[32032.26 30014.60703698 22536.50060264] \[30417.5 28370.38224512 28515.21773692]] \[\[44446.32 37959.57055488 38047.25383688] \[48048.39 45021.91055547 33804.75090396] \[45626.25 42555.57336768 42772.82660539]] \[\[88892.64 75919.14110976 76094.50767375] \[96096.78 90043.82111094 67609.50180792] \[91252.5 85111.14673536 85545.65321077]]]
***Hermoso curso y hermosas las oportunidades de improvisar con el código:*** `arr = np.array([10, 20, 30, 40, 50])` `condicion = arr > 25print("Elementos mayores a 25:", condicion)` `filtrados = arr[arr > 25]print("Elementos filtrados mayores a 25:", filtrados)` `arr2 = np.array([15, 25, 35, 45, 55])comparacion = arr > arr2print("Comparación de los dos arrays (arr > arr2):", comparacion)` `combinado = (arr > 20) & (arr < 50)print("Elementos mayores que 20 y menores que 50:", combinado)` ![](https://static.platzi.com/media/user_upload/image-c0deb665-12d3-4643-ac3f-29a904099407.jpg)
el ultimo ejercicio no me sale igual, en el split\_array no toma algunos numeros del array\_c ![](https://static.platzi.com/media/user_upload/image-f77bc8cd-6c10-43ec-9592-828cf36564c3.jpg)
El segundo ejemplo, es de un broadcasting para realizar una suma de matrices. Sin embargo, se utilizó la variable "discount\_prices" lo que introduce algo de confusión. Este es el código ajustado y comentado para que el ejemplo resulte más explicativo acerca de lo que es broadcasting: ```js prices = np.random.randint(100,500, size=(3,3)) # Array más grande increase = np.array([10,20,30]) # Array más pequeño: broadcastig extiende este vector como si fuera una matriz de 3X3, para hacer la suma de matrices print(prices.shape) # Forma del array prices print(increase.shape) # Forma del arra increase increase_prices = prices + increase # Suma de matrices print(prices) # Matriz original print(increase_prices) # Matriz con incremento ```
```js array_c = np.arange(1,10) split_array = np.split(array_c,3) print(array_c) print(split_array) ```array\_c = np.arange(1,10)split\_array = np.split(array\_c,3)print(array\_c)print(split\_array)
![]()![](https://static.platzi.com/media/user_upload/image-e020c9f6-fd72-4eea-8d40-03cd7ee4e971.jpg)