2017-06-16 97 views
0

我有一個RasterStacks1由包含來自島嶼的數據的400個圖層組成。柵格的範圍被裁剪到島的範圍內,但由於其不規則的形狀,只有大約20%的像素實際上是土地面積並具有數據值;另外80%是水和NA柵格:僅在其他柵格圖層中沒有NA的情況下在RasterStack上計算

我也有一個地水面具lwmRasterLayer),其中土地編碼爲1和水爲NA

我想對s1做不同種類的基於單元格的計算,但注意到這些需要很長時間才能完成。爲了加快速度,只能對土地面積的細胞進行計算,而水域應始終爲NA。在僞代碼中:

for each cell: 
    if cell is land 
     do calculation 
    if cell is water 
     return(NA) 

需求是memory-safety

下面是一些樣本數據來說明問題:

library(raster) 
# generate data 
lwm <- raster(nrow = 5, ncol = 5) 
lwm[] <- c(rep(NA, 10), rep(1, 5), rep(NA, 10)) 

r1 <- raster(nrow = 5, ncol = 5) 
r1[] <- runif(ncell(r1)) * 10 
r2 <- raster(nrow = 5, ncol = 5) 
r2[] <- runif(ncell(r2)) * 10 
s1 <- stack(r1, r2) 
s1 <- mask(s1, lwm) 

# this works, but all NA-values on water are also unnecessarily evaluated 
calc(s1, function(x) {sum(!is.na(x))}) 
+0

在這種情況下,也許它可能是更好地識別非NA單元的索引,只從光柵中提取這些像素,進行計算,然後將結果「返回」到新的光柵中。 – lbusett

+0

這種方法是否安全?在我看來,對於一個非常大的'RasterStack'來說,情況並非如此,是嗎? –

+0

不,這對於非常大的柵格來說不是內存友好的(除非你的「良好數據」區域非常小)。 – lbusett

回答

0

一些玩耍後,我終於找到了這工作得非常好我的情況,並從總體處理時間起飛相當不錯的量的解決方案:

library(raster) 
# generate data 
lwm <- raster(nrow = 50, ncol = 50) 
lwm[] <- 1 

# replace 80% with NA values 
lwm[sample(1:ncell(lwm), round(0.8 * ncell(lwm)))] <- NA 

r1 <- raster(lwm) 
r1[] <- runif(ncell(r1)) 
r1_list <- replicate(400 , r1) 
s1 <- stack(r1_list) 
s1 <- mask(s1, lwm) 

# this works, but all NA-values on water are also unnecessarily evaluated 
system.time(r_sum1 <- calc(s1, function(x) {sum(x)})) 
#user system elapsed 
#0.14 0.00 0.14 

## new approach: 

# stack land-water-mask with RasterStack 
s1_lwm <- stack(lwm, s1) 

# function to check if first element of vector is NA; if yes, return NA; if no, do calculation 
fun1 <- function(y) { 
    if (!is.na(y[1])) { 
    y = y[-1] 
    return(sum(y)) 
    } else { 
     return(NA) 
    } 
} 

system.time(
    r_sum2 <- calc(s1_lwm, fun = fun1) 
) 
# user system elapsed 
# 0.4  0.0  0.4 

# results are identical 
identical(r_sum1[], r_sum2[]) 
0

這是一個棘手和unfortunetely我沒有給你一個直接的解決方案。

您可以做島上的多個作物(即2-3)以最小化NA值,並在每個裁剪柵格上分別進行計算並對結果進行拼接。

或者另一種選擇是做一個並行計算,這將加快顯著的過程:既然你問了一個存儲安全解決方案

#initialize cluster 
    #number of cores to use for clusterR function (max recommended: ncores - 1) 
    beginCluster(3) 

    #calculation 
    result <- clusterR(s1, calc, args=list(fun=function(x) {sum(!is.na(x))})) 

    #end cluster 
    endCluster() 

,你應該看看被多少RAM分配你的時候只有一個核心,然後估計有多少核心可以運行你的計算,所以你不會用完內存。

祝你好運!希望能幫助到你。

+0

感謝您的建議! :) 我應該提到我已經使用了並行計算,並且我正在尋找可以與'clusteR'結合使用的解決方案。 –

+0

這個島上的多種農作物的想法是好的,但會涉及一些預處理和後處理(我希望避免)。 –