r: zПрименить в параллельных вычислениях - PullRequest
4 голосов
/ 16 января 2020

Мне нужно объединить растровые кирпичи в месячные значения. Обычно это было бы легко с помощью функции zApply из пакета raster. Тем не менее, у меня есть большой растровый кирпич, и это заняло бы очень много времени.

Так что, в принципе, мне интересно, было бы легко сделать это с некоторыми библиотеками, такими как 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.

Спасибо!

Ответы [ 2 ]

1 голос
/ 19 января 2020

Несмотря на то, что я обычно поддерживаю весь рабочий процесс в R, это определенно один случай, когда использование внешних приложений, таких как CDO или NCO, намного выгоднее (то есть быстрее). В частности, вы можете использовать CDO операторы monmean или monavg, если хотите, чтобы в ваших временных сериях было среднее значение каждого месяца, или вы можете использовать ymonmean, если вы хотите получить одно среднее значение для каждого месяца. года (т.е. климатология).

Команды будут выглядеть примерно так:

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

, где in.n c будет вашим файлом NetCDF, а out.n c будет ли файл NetCDF получен в результате выполнения команды.

Если ваши файлы разбиты, например, по одному файлу в день, вы можете рассмотреть объединение всего вместе с чем-то вроде:

cdo cat *_daily.nc daily_time_series.nc 
1 голос
/ 16 января 2020

Используйте пакеты foraech и doParallel

Вы можете использовать foreach и doParallel для достижения своего результата. Вам необходимо:

  • Определить количество ядер вашего процессора с помощью detectCores()
  • Инициализировать DoParallel для работы с ядрами вашего процессора с помощью registerDoParallel(numCores)
  • Установите foreach l oop с необходимыми пакетами , любой переменной 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

Как мы видим, благодаря этому методу было достигнуто эффективное улучшение скорости.

Надеюсь, это поможет.

...