Хотя принятый ответ на этот вопрос верен для примера растра, важно отметить, что самая быстрая безопасная функция сильно зависит от размера растра: функции h
и i
, представленные @rengis, работают быстрее только с относительно небольшими растрами (и относительно простая реклассификация). Простое увеличение размера растра r
в примере OP на величину в десять делает reclassify
быстрее:
# Code from OP @AF7
library(raster)
library(microbenchmark)
library(ggplot2)
library(compiler)
#Let's see if precompiling helps speed...
f <- function(x, min, max) reclassify(x, c(-Inf, min, NA, max, Inf, NA))
g <- cmpfun(f)
# Funcions from @rengis
h <- function(r, min, max) {
rr <- r[]
rr[rr < min | rr > max] <- NA
r[] <- rr
r
}
i <- cmpfun(h)
# Benchmark with larger raster (100k cells, vs 10k originally)
r <- raster(ncol = 1000, nrow = 100)
r[] <- runif(ncell(r))
compare <- microbenchmark(
calc(r, fun=function(x){ x[x < 0.2] <- NA; x[x > 0.8] <- NA; return(x)}),
reclassify(r, c(-Inf, 0.2, NA, 0.8, Inf, NA)),
g(r, 0.2, 0.8),
h(r, 0.2, 0.8),
i(r, 0.2, 0.8),
times=100)
autoplot(compare)
Точная точка, когда reclassify
становится быстрее, зависит как от количества ячеек в растре, так и от сложности реклассификации, но в этом случае точка пересечения находится примерно на 50 000 ячеек (см. ниже).
По мере того, как растр становится еще больше (или вычисления усложняются), другим способом ускорить реклассификацию является использование многопоточности, например. с пакетом snow
:
# Reclassify, using clusterR to split into two threads
library(snow)
tryCatch({
beginCluster(n = 2)
clusterR(r, reclassify, args = list(rcl = c(-Inf, 0.2, NA, 0.8, Inf, NA)))
}, finally = endCluster())
Многопоточность влечет за собой еще больше накладных расходов на настройку, и поэтому имеет смысл только с очень большими растрами и/или более сложными вычислениями (на самом деле, я был удивлен, заметив, что это не оказалось лучшим вариантом ни для одной из условия, которые я тестировал ниже — возможно, с более сложной реклассификацией?).
Чтобы проиллюстрировать, я нанес результаты микробенчмарка с использованием настройки OP с интервалами до 10 миллионов ячеек (по 10 прогонов каждой) ниже:
И последнее замечание: компиляция не повлияла ни на один из протестированных размеров.
person
nelliott
schedule
28.03.2016