更改栅格值的并行化

时间:2019-03-07 10:52:11

标签: r parallel-processing spatial raster parallel.foreach

尊敬的stackoverflow社区,

我读了很多关于如何并行化栅格计算的答案。但是,我找不到适合我问题的答案。 我的问题是关于将栅格中的值替换为数据框的并行化。看起来很简单,我找到了一种方法。 但是,我有一个超过500万个像元的栅格和一个超过340 000行的数据框。因此,我的for循环需要很长时间。 因此,我想知道用foreach循环进行计算。我的主要问题是在最后结合我的结果。

我提供了一个简单的示例(摘自:http://j.p.rossi.free.fr/rpackages/ecpaysage/TD_Analyse_quanti_paysage.html#(29)),以使您了解我想做什么:

library(ECPaysage)
library(raster)
r <- raster(system.file("extdata/r.tif", package="ECPaysage")) 
plot(r)

这是我们想要一些补丁信息的土地利用栅格。为此,我们使用SDMTools软件包:

library(SDMTools)
res(r)

matbi <- r
matbi[] <- 0 # let's create the same raster with 0 values
w <- which(r[]==1) 
matbi[w] <- 1 # this creates a binary raster for the specific landuse == 1 

plot(matbi, axes=F, box=F, main="landuse 1 : build") 

我们要从此二进制栅格中创建补丁信息。因此,我们创建了补丁的栅格:

matpatch <- ConnCompLabel(matbi)
plot(matpatch, axes=F,box=F, main="patch ID landuse 1 :build") 

然后,我们从该补丁栅格中提取补丁级别的信息:

patch <- PatchStat(mat=matpatch, cellsize = res(r)[1], latlon = FALSE)
names(patch)

dim(patch)

patch$patchID
dim(patch) 

现在,我们有了栅格中包含的面片数量(每个像元都具有面片ID)。 而且我们要在栅格中提取指定补丁ID的每个像元的补丁值。

shapeindex <- matpatch

w <- which(shapeindex[]==0) # cells that do not belong to any patch
shapeindex[w] <- NA

因此,要为每个补丁ID单元提取相应的补丁索引,请执行for循环:

system.time(for(p in 2:(dim(patch)[1])) {
  w <- which(shapeindex[]==patch$patchID[p])
  shapeindex[w] <- patch$shape.index[p]
})
plot(shape, axes=F,main="shape index - build", box=F, col=rev(terrain.colors(dim(patch)[1]-1))) 

这很好用,但是对于我的数据(超过500万个单元的栅格和超过340 000行的补丁数据帧)来说,这会花费太多时间(这不利于可重复性)。 我的想法之一是将此循环与foreach并行化。但是,我的主要问题是在最后合并我的栅格。如果我在数据帧的行上并行化,我将有340 000矩阵要组合。它可能与for循环花费相同的时间。 因此,我想知道是否存在一种方法(或多种方法,例如函数)来加快处理过程和/或以简单的方式合并栅格。 感谢您提供的所有帮助。 最好, 爱德琳

1 个答案:

答案 0 :(得分:0)

感谢您的回复@ulfelder 我尝试了你所说的。我创建了一个函数,使用lapply并将它们之间的栅格合并:

如果我在循环之前使用前面的代码,它将给出:

if(data.success + '' === 'true') {

但是,我不确定这会更有效...也许,如果栅格变大,则两种方法之间的时间差会减小...

shape <- matpatch
w <- which(shape[]==0)
shape[w] <- NA
class(shape)
shape
plot(shape)

# create my function for one iteration of the for loop
RastVal <- function(monr,vec,i){
  require(raster)
  w <- which(monr[]==vec$patchID[i])
  x <- which(monr[]!=vec$patchID[i])
  monr[w] <- vec$shape.index[i]
  monr[x] <- 0
  return(monr)
}

# create a list of rasters containing the patch information
RastL <- lapply(X=c(2:(dim(patch)[1])),
                   FUN=function(x)RastVal(shape,patch,x))

# Combining the rasters
new.rast <- RastL[[1]]
for(i in 2:length(RastL)){
  x <- RastL[[i]][] != 0
  new.rast[x] <- RastL[[i]][x]
}
plot(new.rast) # should be the same as the raster shape in the previous code
system.time(for(p in 2:(dim(patch)[1])) {
  w <- which(shape[]==patch$patchID[p])
  shape[w] <- patch$shape.index[p]
})
system.time(RastL <- lapply(X=c(2:(dim(patch)[1])),
                   FUN=function(x)RastVal(shape,patch,x)))

此外,创建大约340 000栅格的列表可能会导致内存问题... 再次感谢!

最好, 爱德琳