39 votos

r: aumenta la velocidad de recorte, enmascara y extrae ráster en muchos polígonos

Yo soy la extracción de la zona y por ciento de cobertura de los diferentes tipos de uso de la tierra a partir de una trama basada en varios miles de polígono de límites. He encontrado que el extracto de la función funciona mucho más rápido si me iterar a través de cada polígono y de los cultivos, a continuación, la máscara de la trama hacia abajo para el tamaño de la particular polígono. Sin embargo, es bastante lento, y me pregunto si alguien tiene alguna sugerencia para mejorar la eficiencia y la velocidad de mi código.

La única cosa de la que me he encontrado con esto se relaciona esta respuesta por Roger Bivand que sugirió el uso de GDAL.open() y GDAL.close() así como getRasterTable() y getRasterData(). Miré esos, pero han tenido problemas con gdal en el pasado y no conoce lo suficientemente bien para saber cómo implementarlo.

Reproducible Ejemplo:

library(maptools)  ## For wrld_simpl
library(raster)

## Example SpatialPolygonsDataFrame
data(wrld_simpl) #polygon of world countries
bound <- wrld_simpl[1:25,] #name it this to subset to 25 countries and because my loop is set up with that variable  

## Example RasterLayer
c <- raster(nrow=2e3, ncol=2e3, crs=proj4string(wrld_simpl), xmn=-180, xmx=180, ymn=-90, ymx=90)
c[] <- 1:length(c)

#plot, so you can see it
plot(c)    
plot(bound, add=TRUE) 

Método más rápido hasta el momento

result <- data.frame() #empty result dataframe 

system.time(
     for (i in 1:nrow(bound)) { #this is the number of polygons to iterate through
      single <- bound[i,] #selects a single polygon
      clip1 <- crop(c, extent(single)) #crops the raster to the extent of the polygon, I do this first because it speeds the mask up
      clip2 <- mask(clip1,single) #crops the raster to the polygon boundary

      ext<-extract(clip2,single) #extracts data from the raster based on the polygon bound
      tab<-lapply(ext,table) #makes a table of the extract output
      s<-sum(tab[[1]])  #sums the table for percentage calculation
      mat<- as.data.frame(tab) 
      mat2<- as.data.frame(tab[[1]]/s) #calculates percent
      final<-cbind(single@data$NAME,mat,mat2$Freq) #combines into single dataframe
      result<-rbind(final,result)
      })

   user  system elapsed 
  39.39    0.11   39.52 

El Procesamiento En Paralelo

El procesamiento en paralelo de cortar el tiempo de los usuarios por la mitad, pero negado el beneficio de la duplicación de la hora del sistema. Trama utiliza esto para el extracto de la función, pero por desgracia no para el cultivo o la función de máscara. Por desgracia, esto deja un poquito más grande la cantidad de tiempo transcurrido total debido a "la espera" por el de "IO."

beginCluster( detectCores() -1) #use all but one core

ejecución de código en múltiples núcleos:

  user  system elapsed 
  23.31    0.68   42.01 

después de finalizar el clúster

endCluster()

Lento Método: El método alternativo de hacer un extracto directamente de la trama de la función tiene un montón mucho más tiempo, y no estoy seguro acerca de la gestión de los datos a obtener en la forma que yo quiero:

system.time(ext<-extract(c,bound))
   user  system elapsed 
1170.64   14.41 1186.14 

30voto

TGnat Puntos 2239

He encontrado que al aumentar el maxmemory y chunksize que tengo modestos aumentos de velocidad. Tenía que hacer esto de forma conservadora, porque el tratamiento a veces puede tardar de 3 a 5 veces tanta memoria como la maxmemory (debe ser escrito varios archivos a la que max ajuste de memoria). Aquí está el código para cambiar los ajustes de memoria:

rasterOptions(maxmemory=5e+08,chunksize=5e+07)  #for 500mb max memory (up from 100gb by default), and 50mb of chunk size (up from 10mb).

Yo también soy manualmente subconjunto de los datos en trozos y se ejecuta en varias instancias de R. Incluso con la computación en paralelo (véase el código de arriba), me encontré con el procesamiento tomó alrededor de un 9% max de mi CPU, pero la ejecución de múltiples instancias de R, se utiliza un 9% para cada instancia, así que puede utilizar mucho más de mi capacidad de procesamiento mediante la ejecución de 5-8 casos de R simultáneamente.

Yo todavía me gustaría saber más acerca de tirar de la trama de datos en un rápido formato y ponerlo en la memoria RAM. Siguiendo este ejemplo, he intentado cargar como un SpatialGridDataFrame, el uso de readGDAL() y convertir que a SpatialPixelsDataFrame uso de fullgrid(x) = FALSE, pero mientras que el 32 gigas de ram pueden cargar los 2 gb TIFF archivo raster como SpatialGridDataFrame (tomó alrededor de 25 gb de RAM), no podía aguantar eso y ejecutar el fullgrid(x) = FALSE código sin el funcionamiento de la memoria.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X