es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Sí, existe una forma de vectorizar el cálculo de Y. Puede utilizar la función numpy.any para comprobar si el valor 2 está presente en cada columna de X y luego convertir la matriz booleana resultante a valores enteros mediante numpy.astype. Aquí está 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 = np.any(X == 2, axis=0).astype(int)
    Y = Y.reshape((1, -1))
    assert (Y.shape == (1, m))
    

    La función numpy.any devuelve una matriz booleana de forma (m,) donde True indica que el valor 2 está presente en la columna correspondiente de X. La función numpy.astype convierte esta matriz booleana a una matriz de enteros de forma (m,) con 1 para True y 0 para False. 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 usar numpy.apply_along_axis.

Comments are closed.