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.

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.

Tags:  , , , ,

Answer

  1. Avatar for 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 de large 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:

    # generar arrays de índices para cada dimensión
    y_indices = np.ix_(*[range(y[0], y[1]) for y in boxes_y])
    x_indices = np.ix_(*[range(x[0], x[1]) for x in boxes_x])
    
    # establecer los valores en el array large utilizando los arrays de índices y embebidos
    large[y_indices, x_indices] = embeddings[:, np.newaxis, np.newaxis, :]
    

    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 a np.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 de large.

    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.

Comments are closed.