对R中的栅格堆栈/砖块应用复杂的数学函数,并创建两个相互依赖的不同栅格堆栈

dgsult0t  于 2023-01-28  发布在  其他
关注(0)|答案(1)|浏览(137)

我有一个光栅砖(ncell=28536和nlayers=181)。我需要运行数学函数在原来的砖和创建两个相同大小的砖。其中两个输出砖是相互依赖的。
inputBrick有181层,每层有28536个单元格。outputBrick 1将通过分析outputBrick 2的第1层来计算其第1层的值。然后outputBrick 2将通过分析outputBricks 1的第1层来计算其第2层的值,依此类推。
我创建了一个函数,它在24个单元格和181个层上工作得很好。但是在28000个单元格和181个层上却要花很长时间。我知道我不应该为此使用for循环,但是因为我不是一个程序员,所以我很挣扎。
以下是一个小得多的数据集的一些示例数据。有3个RasterBrick。输入具有值,而两个输出均为空

library(raster)
b <- brick(ncols=5, nrows=5, nl=5)
inBrick <- setValues(b, runif(ncell(b) * nlayers(b)))
inBrick[c(1,2,3,22,23,24,25)] <- NA
outBrick1 <- inBrick
outBrick1[] <- NA
outBrick2 <- outBrick1

ini <- 0.3
p <- 0.15
p1 <- p/3
p2 <- p-(p/3)
fc <- 0.3
var1 <- which(!is.na(inBrick[[1]][]))

outBrick2[[1]][var1] <- ini
### now outBrick2 has initial values in 1st layer
weather <- c(0.1, 0, 0, 0, 0.3)

我想进行计算,但不知道如何在不使用for循环的情况下高效地进行计算

var3 <- 1:ncell(inBrick)
### outBrick1 Calculations
for (i in 1:nlayers(inBrick)) {
varr1 <- inBrick[[i]][]*(((outBrick2[[i]][]-p1)/(p2))^2)
for (j in 1:ncell(inBrick)) {
if(!is.na(outBrick2[[i]][j])){
  if(outBrick2[[i]][j]>p){
     outBrick1[[i]][j] <- inBrick[[i]][j]
  }else{
     outBrick1[[i]][j] <- varr1[j]
    }
  }
}
###outBrick2 Calculations
for (k in 2:nlayers(inBrick)) {
var2 <- outBrick2[[k-1]][] + (weather[k-1]-outBrick1[[k-1]][])/100
 for(l in 1:ncell(inBrick)){
  var3[l] <- min(fc, var2[l])
 }
 outBrick2[[k]][] <- var3
 }
}

现在,我想基本了解一下处理这种情况的最佳方法是什么。我也尝试过通过以下命令来增加内存

rasterOptions(maxmemory = 5.17e+10)
rasterOptions(memfrac = 0.8)
rasterOptions(chunksize = 5.17e+10)

但是当我看到CPU和RAM的使用率分别只有6%和10%。R只使用5%的CPU和1GB RAM。我的系统有64 GB RAM,16 GB GPU。

hkmswyz6

hkmswyz61#

这里是一个尝试。这要简洁得多。在这个例子中只快了三倍,但在你的真实的数据中增益可能更大。

library(terra)
b <- r1 <- r2 <- rast(ncols=5, nrows=5, nl=5, vals=NA)
set.seed(0)
values(b) <- runif(size(b))
b[c(1,2,3,22,23,24,25)] <- NA

p  <- 0.15
p1 <- p/3
p2 <- p-(p/3)
fc <- 0.3
weather <- c(0.1, 0, 0, 0, 0.3)

r2[[1]] <- ifel(is.na(b[[1]]), NA, 0.3)

for (i in 1:nlyr(b)) {
    varr1 <- b[[i]] * (((r2[[i]] - p1)/p2)^2)
    r1[[i]] <- ifel(r2[[i]] > p, b[[i]], varr1)
    for (k in 2:nlyr(b)) {
        r2[[k]] <- min(r2[[k-1]] + (weather[k-1] - r1[[k-1]]) /100, fc)
    }
}

如果速度是问题所在,并且光栅数据可以加载到RAM中,则这可能会快得多:

db  <- values(b)
dr1 <- values(r1)
dr2 <- values(r2)

for (i in 1:ncol(db)) {
    varr1 <- db[, i] * (((dr2[, i] - p1)/p2)^2)
    dr1[,i] <- ifelse(dr2[, i] > p, db[, i], varr1)
    for (k in 2:ncol(b)) {
        dr2[,k] <- pmin(dr2[, k-1] + (weather[k-1] - dr1[, k-1]) /100, fc)
    }
}

values(r1) <- dr1
values(r2) <- dr2

相关问题