Skip to main content

2 posts tagged with "numpy"

View All Tags

· 11 min read
Darvin Cotrina

Broadcasting con NumPy

image.png

El broadcasting es una forma de hacer operaciones entre arrays de diferentes tamaños, que usualmente no son compatibles. El broadcasting es posible cuando se cumplen ciertas reglas.

  • El tamaño de cada dimensión es igual.
  • Una de las dimensiones es 1.

El broadcasting se realiza en la dimensión que tiene tamaño 1. El array con tamaño 1 se extiende para que tenga el mismo tamaño que el otro array.

Ejemplos de broadcasting

Array 1Array 2Resultado
10 x 51 x 510 x 5
10 x 5510 x 5
10 x 510 x 110 x 5
10 x 5scalar10 x 5
import numpy as np
from rich import print
# matris de 10x5
m10_5 = np.random.randint(0, 10, (10, 5))
m1_5 = np.random.randint(0, 10, (1, 5))
m5 = np.random.randint(0, 10, (5))
m10_1 = np.random.randint(0, 10, (10, 1))
scalar = 5

print('Broadcasting de 10x5 + 1x5')
print(m10_5 + m1_5)
print('Broadcasting de 10x5 + 5')
print(m10_5 + m5)
print('Broadcasting de 10x5 + 10x1')
print(m10_5 + m10_1)
print(m10_5 + scalar)
Broadcasting de 10x5 + 1x5
[[ 9  2  6  5  1]
 [ 5  9 10 10  8]
 [ 6  9  3 10  3]
 [ 8  8  7  4  8]
 [ 5  2  6 10  5]
 [ 7  9  9  8  3]
 [ 7  5  3  5  7]
 [ 4  7  7  3  1]
 [ 2  8  6 12  7]
 [ 9  9 12 10 10]]
Broadcasting de 10x5 + 5
[[ 7 11  9  2  5]
 [ 3 18 13  7 12]
 [ 4 18  6  7  7]
 [ 6 17 10  1 12]
 [ 3 11  9  7  9]
 [ 5 18 12  5  7]
 [ 5 14  6  2 11]
 [ 2 16 10  0  5]
 [ 0 17  9  9 11]
 [ 7 18 15  7 14]]
Broadcasting de 10x5 + 10x1
[[14  9 10  9  7]
 [ 5 11  9  9  9]
 [ 5 10  1  8  3]
 [11 13  9  6 12]
 [ 9  8  9 13 10]
 [11 15 12 11  8]
 [ 6  6  1  3  7]
 [ 3  8  5  1  1]
 [ 8 16 11 17 14]
 [ 7  9  9  7  9]]
[[12  7  8  7  5]
 [ 8 14 12 12 12]
 [ 9 14  5 12  7]
 [11 13  9  6 12]
 [ 8  7  8 12  9]
 [10 14 11 10  7]
 [10 10  5  7 11]
 [ 7 12  9  5  5]
 [ 5 13  8 14 11]
 [12 14 14 12 14]]

Ejemplos de no broadcasting

Array 1Array 2Resultado
10 x 55 x 10Error
10 x 510Error
m10_5 = np.random.randint(0, 10, (10, 5))
m5_10 = np.random.randint(0, 10, (5, 10))
m10 = np.random.randint(0, 10, (10))

print('Broadcasting de 10x5 + 5x10')
print(m10_5 + m5_10)
Broadcasting de 10x5 + 5x10
ValueError: operands could not be broadcast together with shapes (10,5) (5,10) 
print('Broadcasting de 10x5 + 10')
print(m10_5 + m10)
Broadcasting de 10x5 + 10
ValueError: operands could not be broadcast together with shapes (10,5) (10,) 

· One min read
Darvin Cotrina

Tanto numpy como pandas tienen funciones que permiten aplicar una funcion a un array o dataframe, respectivamente, de forma vectorizada. Esto significa que la funcion se aplica a todos los elementos del array o dataframe, sin necesidad de iterar sobre ellos. Esto es mucho mas eficiente que iterar sobre los elementos, ya que no se necesita hacer un loop en python, sino que la funcion se aplica en C.

import numpy as np
import pandas as pd

# comparación de vectorize de numpy vs apply de pandas

# vectorize de numpy
def f(x):
return x**2 + 1

array = np.arange(100000, dtype=np.int16)

%timeit np.vectorize(f)(array)
# pandas apply
df = pd.DataFrame({'x': array})
%timeit df['x'].apply(f)
24.2 ms ± 1.56 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
40.7 ms ± 1.01 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

Esta es una comparación muy simple entre ambas formas de aplicar una funcion, pero nos da una idea bastante clara de la diferencia de performance entre ambas, como podemos ver vectorize fue mucho mas rapido que apply.