代码之家  ›  专栏  ›  技术社区  ›  Andrei Niță

r: z应用于并行计算

  •  2
  • Andrei Niță  · 技术社区  · 5 年前

    我需要将一个rasterbrick汇总为每月值。通常,通过使用 zApply 功能从 raster 包裹。然而,我有一个很大的rasterbrick,这需要很长时间。

    所以基本上,我想知道这是否很容易用一些库来实现,比如 parallel clusterR 但我不知道如何并行化这个过程

    # 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.
    

    谢谢!

    0 回复  |  直到 5 年前
        1
  •  1
  •   Louis    5 年前

    使用foraech和doParallel软件包

    您可以使用 foreach doParallel 为了达到你的目标。 您需要:

    • 使用检测您的CPU核数 detectCores()
    • 初始化 DoParallel 使用CPU内核 registerDoParallel(numCores)
    • 设置 foreach 循环与所需 包装 ,任何 init 变量,以及一种方法 结合 结果。

    你的代码看起来像这样:

    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
    

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

    希望这能有所帮助。

        2
  •  1
  •   thiagoveloso    5 年前

    虽然我通常喜欢把所有的工作流程都放在里面 R ,这绝对是使用外部应用程序的一个例子,例如 CDO NCO 更有益(即更快)。特别是,您可以使用 CDO 操作员 monmean monavg 如果你想得到时间序列中每个月的平均值,或者你可以使用 ymonmean 如果你想要一年中每个月的平均值(即气候学)。

    命令看起来像:

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

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

    如果你的文件被拆分,例如每天一个文件,你可能会考虑将所有内容连接在一起,比如:

    cdo cat *_daily.nc daily_time_series.nc