Quiero calcular una suma de peso indexada en una gran matriz numerada booleana (1,000,000 x 3,000). La gran matriz booleana cambia con poca frecuencia, pero los pesos vienen en tiempo de consulta, y necesito respuestas muy rápido, sin copiar toda la matriz grande, o expandir la matriz de pesas pequeñas al tamaño de la matriz grande.¿Sumar de manera eficiente una matriz numpy pequeña, transmitida a través de una matriz numpy descomunal?
El resultado debe ser una matriz con 1,000,000 entradas, cada una con la suma de las entradas de la matriz de ponderaciones correspondientes a los valores True de esa fila.
Analicé el uso de matrices enmascaradas, pero parecen requerir la construcción de una matriz de pesos del tamaño de mi matriz booleana grande.
El código siguiente muestra los resultados correctos, pero no puedo permitirme esa copia durante el paso de multiplicar. La multiplicación ni siquiera es necesaria, ya que la matriz de valores es booleana, pero al menos maneja la difusión correctamente.
Soy nuevo en numpy, y me encanta, pero estoy a punto de renunciar a él por este problema en particular. Aprendí lo suficiente para saber que me quedé lejos de cualquier cosa que se repita en python.
Mi próximo paso será escribir esta rutina en C (que tiene el añadido beneficio de dejar a salvar la memoria mediante el uso de los bits en lugar de bytes, por el camino.)
A menos que uno de ustedes gurús numpy me puede salvar de cython?
from numpy import array, multiply, sum
# Construct an example values array, alternating True and False.
# This represents four records of three attributes each:
# array([[False, True, False],
# [ True, False, True],
# [False, True, False],
# [ True, False, True]], dtype=bool)
values = array([(x % 2) for x in range(12)], dtype=bool).reshape((4,3))
# Construct example weights, one for each attribute:
# array([1, 2, 3])
weights = array(range(1, 4))
# Create expensive NEW array with the weights for the True attributes.
# Broadcast the weights array into the values array.
# array([[0, 2, 0],
# [1, 0, 3],
# [0, 2, 0],
# [1, 0, 3]])
weighted = multiply(values, weights)
# Add up the weights:
# array([2, 4, 2, 4])
answers = sum(weighted, axis=1)
print answers
# Rejected masked_array solution is too expensive (and oddly inverts
# the results):
masked = numpy.ma.array([[1,2,3]] * 4, mask=values)
Buen trabajo con el ejemplo de lo que necesita. – steveha