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.

¿Existe un método más rápido para iterar sobre un arreglo numpy 2D muy grande que no sea utilizando np.where?

Tengo una gran matriz numpy 2D llena de valores enteros. Los recojo de una .tif-imagen a través de gdal.GetRasterBand().
Los valores de los píxeles de la imagen representan números de identificación de clúster únicos. Por lo tanto, todos los píxeles dentro de un clúster tienen el mismo valor.
En mi script, quiero comprobar si los clústeres tienen más píxeles que un umbral específico. Si el tamaño del clúster es mayor que el umbral, quiero mantener el clúster y darles un valor de píxel 1. Si un clúster tiene menos píxeles que el umbral, todos los píxeles de este clúster deben tener el valor 0.

Hasta ahora, mi código funciona, pero es muy lento. Y como quiero variar el umbral, lleva una eternidad.
Apreciaría mucho su ayuda. Gracias.

“`

Importar GeoTIFF a través de GDAL y convertirlo a NumpyArray

data = gdal.Open(image)
raster = data.GetRasterBand(1)
raster = raster.ReadAsArray()

Diferentes umbrales para la iteración

thresh = [0,10,25,50,100,1000,2000]

for threshold in thresh:
clusteredRaster = np.array(raster.copy(), dtype = int)

    for clump in np.unique(clusteredRaster): # Identificadores únicos de los clústeres en la imagen

        if clusteredRaster[np.where(clusteredRaster == clump)].size >= threshold: 
            clusteredRaster[np.where(clusteredRaster == clump)] = int(1)

        else:
            clusteredRaster[np.where(clusteredRaster == clump)] = int(0)

”’

Imagen de clústeres

En la imagen se pueden ver los clústeres. Cada color representa un número de clúster específico. Quiero eliminar los más pequeños (por debajo de un tamaño específico) y solo conservar los más grandes.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Optimización de código para la selección del tamaño del clúster

    Problema

    El código anterior tarda mucho en ejecutarse debido a la naturaleza iterativa de recorrer los identificadores únicos de los clústeres y verificar su tamaño con respecto a cada umbral.

    Solución

    Una forma más eficiente de verificar los tamaños de los clústeres es utilizar la funcionalidad incorporada en numpy. Podemos usar la función bincount para obtener un recuento de los identificadores únicos y sus tamaños respectivos. Luego, podemos utilizar la indexación booleana para asignar los valores de píxeles según el umbral.

    # Importar GeoTIFF mediante GDAL y convertirlo en un NumpyArray
    data = gdal.Open(image)
    raster = data.GetRasterBand(1)
    raster = raster.ReadAsArray()
    
    # Diferentes umbrales para la iteración
    thresh = [0,10,25,50,100,1000,2000]
    
    for threshold in thresh:
        clusteredRaster = np.array(raster.copy(), dtype=int)
    
        # Obtener el recuento de los identificadores únicos de los clústeres y sus tamaños
        ids, counts = np.unique(clusteredRaster, return_counts=True)
    
        # Asignar valores de píxeles según el umbral
        clusteredRaster[np.isin(clusteredRaster, ids[counts >= threshold])] = 1
        clusteredRaster[~np.isin(clusteredRaster, ids[counts >= threshold])] = 0
    
    

    Esto debería reducir significativamente el tiempo de ejecución del código, especialmente al tratar con conjuntos de datos más grandes. Tenga en cuenta que esta solución asume que los identificadores de los clústeres son enteros sin lagunas en la secuencia. Si hay lagunas o identificadores que no son enteros, puede ser necesaria una aproximación diferente.

Comments are closed.