NumPy llenando valores dentro de coordenadas de cuadro delimitador para una matriz grande
Tengo una matriz tridimensional muy grande
py
large = np.zeros((2000, 1500, 700))
En realidad, large
es una imagen pero para cada coordenada, tiene 700 valores. Además, tengo 400 cajas delimitadoras. Las cajas delimitadoras no tienen una forma fija. Almaceno una tupla de coordenadas límite inferiores y superiores para cada caja de la siguiente manera
py
boxes_y = [(y_lower0, y_upper0), (y_lower1, y_upper1), ..., (y_lower399, y_upper399)]
boxes_x = [(x_lower0, x_upper0), (x_lower1, x_upper1), ..., (x_lower399, x_upper399)]
Luego, para cada caja, quiero llenar la región correspondiente en la matriz large
con un vector de tamaño 700. Específicamente, tengo una matriz embeddings
para cada caja
py
embeddings = np.random.rand(400, 700) # En el caso real, estos no son aleatorios. Solo considere la forma
Lo que quiero hacer es
py
for i in range(400):
large[boxes_y[i][0]: boxes_y[i][1], boxes_x[i][0]: boxes_x[i][1]] = embeddings[i]
Esto funciona pero es demasiado lento para una matriz tan grande de large
. Estoy buscando vectorizar este cálculo.
davy.ai
Una posible manera de vectorizar este cálculo es utilizar la función
np.ix_()
para generar arrays de índices que luego se utilizarán para establecer los valores delarge
en una sola operación. Este enfoque evita el uso de un bucle y puede mejorar significativamente el rendimiento.Aquí hay un ejemplo de implementación:
En esta implementación, primero generamos arrays de índices para cada dimensión utilizando
np.ix_()
. La comprensión del bucle interno genera una lista de rangos para cada caja, que se pasa anp.ix_()
para generar el correspondiente array de índices.Luego, utilizamos los arrays de índices para establecer los valores de
large
mediante broadcasting. El array de embebidos se reordena para agregar dos dimensiones adicionales (una para cada array de índices), de manera que se obtiene un array tridimensional con forma(400, rango_y, rango_x, 700)
. Luego, utilizamos broadcasting para asignar este array a la región correspondiente delarge
.Este enfoque debería ser significativamente más rápido que utilizar un bucle, ya que evita el costo de establecer los valores uno por uno en un bucle.