Vectorizar “está en”
Intento construir muestras de m
vectores (con entradas enteras) junto con m
evaluaciones. Un vector x
de forma (n,1)
se evalúa como y=1
si una de sus entradas es el número 2
. De lo contrario, se evalúa como y=0
.
Para manejar muchos vectores y evaluaciones de este tipo, los vectores de muestra se almacenan en un ndarray
de forma (n,m)
y las evaluaciones se almacenan en un ndarray
de forma (1,m)
. Vea el código:
import numpy as np
n = 10 # número de entradas en cada vector de muestra
m = 1000 # número de muestras
X = np.random.randint(-10, 10, (n, m))
Y = []
for i in range(m):
if 2 in X[:, i]:
Y.append(1)
else:
Y.append(0)
Y = np.array(Y).reshape((1,-1))
assert (Y.shape == (1,m))
¿Cómo puedo vectorizar el cálculo de Y
? Intenté reemplazar la inicialización/cálculo de X
y Y
por lo siguiente:
python3
X = np.random.randint(-10,10,(n,m))
Y = np.apply_along_axis(func1d=lambda x: 1 if 2 in x else 0, axis=0, arr=X)
Algunas ejecuciones sugirieron que esto en la mayoría de las veces incluso es un poco más lento que mi primer enfoque. (En realidad, esta respuesta comienza diciendo que numpy.apply_along_axis
no fue diseñado para velocidad. Además, no estoy seguro de qué tan bueno es lambda
en este contexto).
¿Hay alguna manera de vectorizar el cálculo de Y
, es decir, una forma de asignar un valor 1
o 0
a cada columna, dependiendo de si esa columna contiene el elemento 2
?
davy.ai
Sí, existe una forma de vectorizar el cálculo de
Y
. Puede utilizar la funciónnumpy.any
para comprobar si el valor2
está presente en cada columna deX
y luego convertir la matriz booleana resultante a valores enteros mediantenumpy.astype
. Aquí está el código:La función
numpy.any
devuelve una matriz booleana de forma(m,)
dondeTrue
indica que el valor2
está presente en la columna correspondiente deX
. La funciónnumpy.astype
convierte esta matriz booleana a una matriz de enteros de forma(m,)
con1
paraTrue
y0
paraFalse
. Finalmente,Y
se redimensiona para tener una forma(1, m)
para que sea consistente con la implementación original. Este enfoque debería ser más rápido que usarnumpy.apply_along_axis
.