r:z应用于并行计算



我需要将栅格砖聚合为每月值。通常,通过使用raster包中的zApply函数很容易。但是,我有一个大的光栅砖,这将需要很长时间。

所以基本上,我想知道这是否很容易用一些库(如parallelclusterR(做到这一点,但我不知道如何并行化这个过程

# create a random raster stack
library(raster)
lay <- stack()
for (i in 1:365){
print(i)
ras <- matrix(rnorm(500, mean = 21, sd = rnorm(21, 12, 4)))
ras <- raster(ras)
lay <- addLayer(lay, ras)
}
dats <- seq(as.Date('2000-01-01'), length.out = nlayers(lay), by = 'days')
lay <- setZ(lay, dats)
monthlies <- zApply(lay, by = format(dats,"%m"), fun = 'mean') # aggregate from daily to monthly.

谢谢!

使用 foraech 和 doParallel 包

您可以使用foreachdoParallel来实现结果。 您将需要:

  • 使用detectCores()检测 CPU 内核的数量
  • 初始化DoParallel以使用具有registerDoParallel(numCores)的 CPU 内核
  • 使用所需的、任何init变量和组合结果的方法设置foreach循环。

您的代码将如下所示:

library(foreach)
library(doParallel)
library(raster)
lay <- stack()
## Loading required package: iterators
numCores <- detectCores()
registerDoParallel(numCores)  # use multicore, set to the number of our cores
lay <- foreach (i=1:365, .init = lay, .combine = addLayer , .packages = "raster") %dopar% {
print(i)
ras <- matrix(rnorm(500, mean = 21, sd = rnorm(21, 12, 4)))
ras <- raster(ras)
}
dats <- seq(as.Date('2000-01-01'), length.out = nlayers(lay), by = 'days')
lay <- setZ(lay, dats)
monthlies <- zApply(lay, by = format(dats,"%m"), fun = 'mean') # aggregate from daily to monthly
# When you're done, clean up the cluster
stopImplicitCluster()

测量速度提高

您可以使用System.time()测试速度改进。这些是我的结果:

#Time with a standard for loop
system.time({
for (i in 1:365){
print(i)
ras <- matrix(rnorm(500, mean = 21, sd = rnorm(21, 12, 4)))
ras <- raster(ras)
lay <- addLayer(lay, ras)
}
})
user  system elapsed 
66.29    0.09   67.15 
#Testing foreach loop time
system.time({
lay <- foreach (i=1:365, .init = lay, .combine = addLayer , .packages = "raster") %dopar% {
print(i)
ras <- matrix(rnorm(500, mean = 21, sd = rnorm(21, 12, 4)))
ras <- raster(ras)
}
})
user  system elapsed 
21.72    0.09   25.58

如我们所见,使用这种方法可以有效地提高速度。

希望这有帮助。

虽然我通常喜欢将所有工作流程都保留在R,但这绝对是使用外部应用程序(如CDONCO(更有益(即更快(的一个例子。特别是,如果您想在时间序列中拥有每个月的平均数,您可以使用CDO运算符monmeanmonavg,或者如果您希望一年中每个月(即气候学(的单个平均值,则可以使用ymonmean

这些命令将如下所示:

cdo monmean in.nc out.nc
cdo ymonmean in.nc out.nc

其中 in.nc 是 NetCDF 文件,out.nc 是命令生成的 NetCDF 文件。

如果文件被拆分,例如,每天一个文件,则可以考虑将所有内容连接在一起,如下所示:

cdo cat *_daily.nc daily_time_series.nc