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.

Más Vectorización de Numpy en lugar de utilizar bucles anidados.

Tengo all_data como una matriz numpy con un tamaño de (2,601), NUM_SAMPLES = 601 y NUM_CLUSTERS = 3.
¿Existe alguna forma de construir f (una matriz numpy de (601,9)) en forma de vector que no implique el uso de bucles anidados como se muestra a continuación?

f = np.empty((0,9), float)
for n in range(NUM_SAMPLES):
f_n = np.array([[]])
for m in range(NUM_CLUSTERS):
f_n = np.hstack( (f_n , z_i(alldata[:,n], m).T))
f = np.concatenate((f, f_n) , axis=0)

NOTA: al recordar la función z_i(alldata[:,n], m), devuelve una matriz numpy de (3,1).

f se supone que es ‘F’ en la siguiente fórmula:
fórmula de f

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Sí, hay una forma vectorizada de construir f sin utilizar bucles for anidados. Puede usar la función de broadcast de numpy para simplificar el código. Aquí hay un ejemplo de código:

    z = np.array([z_i(all_data, m).T for m in range(NUM_CLUSTERS)])  # forma: (3, 1, 601)
    z = np.repeat(z, 9, axis=1)  # forma: (3, 9, 601)
    pesos = np.array([2,1,3,1,2,3,3,2,1])
    w = np.repeat(pesos.reshape((-1, 1)), NUM_SAMPLES, axis=1)  # forma: (9, 601)
    f = np.sum(z * w, axis=0).T  # forma: (601, 9)
    

    Explicación:

    1. Primero, creamos una matriz numpy z con una forma de (3,1,601) que contiene los resultados de z_i para cada valor de m y n. Esto se puede hacer utilizando una comprensión de lista y np.array(). Agregamos una nueva dimensión de tamaño 1 usando .T para obtener una forma de (3,1), que es el tamaño de la matriz devuelta por z_i().
    2. Luego usamos la función repeat() de numpy para repetir z a lo largo del segundo eje (eje=1) 9 veces, por lo que la forma resultante es(3,9,601). Esto crea una matriz compatible con la transmisión para los pesos.
    3. A continuación, creamos una matriz numpy 2D w con forma (9,601), que contiene los pesos para cada componente de f. Esto se hace simplemente repitiendo la matriz de pesos con forma (9,) a lo largo del segundo eje utilizando repeat() y remodelándola con .reshape((-1,1)).
    4. Luego aplicamos la multiplicación elemento a elemento de z y w para obtener una matriz de forma (3,9,601).
    5. Finalmente, sumamos a lo largo del primer eje (eje=0) y transponemos la matriz resultante para obtener una matriz de forma (601,9).

    Esta forma vectorizada del código debería ser más rápida que los bucles for anidados para matrices grandes.

Comments are closed.