Vectorizando una operación de Numpy en matrices de formas diferentes.
No puedo encontrar una solución al siguiente problema:
Considera dos numpy.arreglos, uno con forma (10, 64, 10) y otro de (x, 64).
El arreglo A (10, 64, 10) representa 10 clases con 64 características y para cada una de estas características tengo una PDF dividida en 10 intervalos -> (Clases, Características, Intervalos). Cada valor en ese arreglo más interno representa una probabilidad.
Ejemplo:
[[[0.62, 0., 0. ],
[0.12, 0.09, 0.01],
[0.59, 0.01, 0. ],
[0.62, 0., 0. ]],
[[0.62, 0., 0. ],
[0.59, 0.01, 0. ],
[0.62, 0., 0. ],
[0.62, 0., 0. ]]]
El arreglo B (X, 64) son las instancias de un conjunto de datos X y el índice de intervalo al que pertenece la i-énesima característica.
Ejemplo:
[[0, 0, 2, 1]
[0, 0, 1, 0]
[0, 2, 1, 0]]
Lo que quiero hacer es para cada fila en el arreglo B, por ejemplo [0, 0, 2, 1] quiero obtener la probabilidad de que cuando el intervalo para la primera característica es 0 la clase es “1” y que la clase es “0”.
La salida esperada para la primera instancia sería:
“0” = [0.62, 0.12, 0.00, 0.00]
“1” = [0.62, 0.59, 0.00, 0.00]
y si es posible, para todas las X instancias.
No espero ningún tipo de diccionario o algo similar, sino simplemente un arreglo que contenga los valores de una manera algo ordenada (puede ser otro orden que el mostrado en el ejemplo).
Por supuesto, podría hacer todo esto con bucles anidados gigantes, pero quiero al menos algo de vectorización. ¿Alguien tiene alguna buena sugerencia, o la respuesta no tiene que ser una solución completamente elaborada?
EDICIÓN: La mejor anidación que se me ocurrió fue:
prediction = np.empty((bins.shape[0], histograms.shape[1], histograms.shape[0]))
for n, instance in enumerate(bins):
for i, instance_bin in enumerate(instance):
prediction[n,i] = histograms[:,i, instance_bin] # Prob for every class x that the bin given in "instance_bin" of feature "i" corresponds to a possible instance of that class
donde histograms
sería el arreglo A y bins
sería el arreglo B.
Por favor, díganme también cualquier otra práctica deficiente que encuentren en mi forma de trabajar con numpy u cualquier otra cosa en este fragmento.
davy.ai
Para obtener la probabilidad de que, cuando el contenedor para la primera característica es 0, la clase sea “1” y que la clase sea “0”, puede usar la indexación de numpy para seleccionar las probabilidades adecuadas de la matriz A. Específicamente, puede usar la indexación avanzada de numpy para seleccionar elementos de la matriz A utilizando los índices de la matriz B. Aquí hay un código para lograr esto:
Esto debería imprimir lo siguiente:
La matriz
prob_0
contiene las probabilidades para la clase “0” y la matrizprob_1
contiene las probabilidades para la clase “1”. Cada fila en estas matrices corresponde a una fila en la matriz B. Por ejemplo, la primera fila deprob_0
corresponde a la primera fila de la matriz B, que es[0, 0, 2, 1]
.En cuanto a las malas prácticas, su solución de bucle anidado no es óptima porque no aprovecha completamente las capacidades de numpy para una computación eficiente. Usar la indexación avanzada de numpy como se muestra arriba es una solución mucho más eficiente. Otro problema potencial es con la nombración de sus variables. Por ejemplo,
bins
es un nombre engañoso para la matriz B porque implica que contiene valores de contenedores, cuando de hecho contiene índices de contenedores. El uso de nombres de variables más descriptivos puede ayudar a que su código sea más legible y menos propenso a errores.