Я извлекаю площадь и процент покрытия различных типов землепользования из растра, основанного на нескольких тысячах границ полигонов. Я обнаружил, что функция извлечения работает намного быстрее, если я перебираю каждый отдельный многоугольник и обрезаю, а затем маскирую растр до размера определенного многоугольника. Тем не менее, это довольно медленно, и мне интересно, есть ли у кого-нибудь предложения по повышению эффективности и скорости моего кода.
Единственное, что я нашел в связи с этим, - это ответ Роджера Биванда, который предложил использовать GDAL.open()
и GDAL.close()
так же, как getRasterTable()
и getRasterData()
. Я изучал их, но в прошлом у меня были проблемы с gdal, и я не знаю этого достаточно хорошо, чтобы знать, как это реализовать.
Воспроизводимый пример:
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)
Самый быстрый метод на данный момент
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
Параллельная обработка
Параллельная обработка сократила время пользователя вдвое, но свела на нет преимущество, удвоив системное время. Растр использует это для функции извлечения, но, к сожалению, не для функции обрезки или маски. К сожалению, из-за «ожидания» с помощью «IO» остается немного больше общего истекшего времени .
beginCluster( detectCores() -1) #use all but one core
запустить код на нескольких ядрах:
user system elapsed
23.31 0.68 42.01
затем завершить кластер
endCluster()
Медленный метод: альтернативный метод извлечения непосредственно из растровой функции занимает намного больше времени, и я не уверен насчет управления данными, чтобы получить его в нужной форме:
system.time(ext<-extract(c,bound))
user system elapsed
1170.64 14.41 1186.14