大型数据集的算术函数应该使用哪个包,terra还是raster?

7rtdyuoh  于 2023-01-28  发布在  其他
关注(0)|答案(2)|浏览(184)

我需要在很多大栅格(28000个单元,181层)上做计算。我在一个小子集(24cell,181层)上尝试了我的代码。我从这个论坛得到了帮助,尽我所能优化。
现在我在光栅包中使用砖块,因为我读到砖块被加载到内存中,并且处理起来更快。但是有些人认为terra比光栅更好更容易。
我用两个软件包来运行我的代码,我发现光栅在我的情况下更快(9分钟比16分钟)。现在这个时间是一个小数据集。当我运行它的原始数据的计算机永远。当我检查CPU和RAM使用的计算机在这个过程中分别约16%和约1GB。即使我的代码是低效的,为什么R不使用可用的RAM和CPU。
我尝试做的是实现一个模型,我必须使用样条函数将Landsat NDVI插值到每天的时间步长。然后使用数学方程计算不同的变量。有些非常简单明了,但有些非常复杂。
我想要的是一种计算不同变量的有效方法。
如果有人能解释一下,我们将不胜感激:
1.即使我的代码效率很低,我相信计算机应该使用最大的可用资源,有办法做到吗?
1.光栅包在我的情况下更好吗?
1.我看到一些人在推荐并行处理。因为我不是程序员,所以我必须在实现之前阅读它。虽然我知道它是什么。
很抱歉没有提出的问题,因为他们应该是第一次。希望这是在更好的形状现在。谢谢
下面是可复制的terra代码(特别感谢Robert Hijmans):

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)
    }
}

以下是可复制的光栅代码:

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)
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
 }
}
hgb9j2n6

hgb9j2n61#

“terra”通常更快,有时要快得多。nukubiho指出,在算术计算中,“raster”可能比“terra”更快。然而,这种差异通常很小,而且可能只在单元值在内存中时才成立。
然而,这可能不适用于大型数据集(在大型数据集中,这些差异可能很重要)。这些数据集的单元格值通常在一个文件中。
在内存中:

library("raster")
library("terra")

n = 12000
x_terra = rast(nrows = n, ncols = n, vals = rnorm(n ^ 2))
y_terra = rast(nrows = n, ncols = n, vals = rnorm(n ^ 2))

x_raster = raster(x_terra)
y_raster = raster(y_terra)
r <- c(x_terra, y_terra)

system.time({ (x_raster - y_raster) / (x_raster + y_raster) })
#   user  system elapsed 
#   1.83    0.36    2.19 
system.time({ (x_terra - y_terra) / (x_terra + y_terra) })
#   user  system elapsed 
#   2.66    2.25    4.91 
system.time(app(r, \(x) (x[,1]-x[,2]) / (x[,1] + x[,2])))
#   user  system elapsed 
#   4.06    2.17    6.25

“raster”更快。但是当值在文件中时,“terra”更快。

x_terra = writeRaster(x_terra, "test1.tif", overwrite=T)
y_terra = writeRaster(y_terra, "test2.tif", overwrite=T)
x_raster = raster(x_terra)
y_raster = raster(y_terra)
r <- c(x_terra, y_terra)

system.time({ (x_raster - y_raster) / (x_raster + y_raster) })
#   user  system elapsed 
#  17.25    5.39   22.66 
system.time({ (x_terra - y_terra) / (x_terra + y_terra) })
#   user  system elapsed 
#  13.63    4.92   18.61 
system.time(app(r, \(x) (x[,1]-x[,2]) / (x[,1] + x[,2])))
#   user  system elapsed 
#   9.78    3.46   13.24
inkz8wg9

inkz8wg92#

一般来说,terra比raster快,但内存中的算术计算是个例外。原因可能是raster使用了经过高度优化的R代码。请看这个简单的例子:

library("raster")
library("terra")

n = 12000
x_terra = rast(nrows = n, ncols = n, vals = rnorm(n ^ 2))
y_terra = rast(nrows = n, ncols = n, vals = rnorm(n ^ 2))
x_raster = raster(x_terra)
y_raster = raster(y_terra)

## terra
system.time({ (x_terra - y_terra) / (x_terra + y_terra) })
#> user  system elapsed
#> 2.63    2.22    4.86

## raster
system.time({ (x_raster - y_raster) / (x_raster + y_raster) })
#> user  system elapsed
#> 1.78    0.26    2.05

如果您想使用更多的CPU和RAM,那么也许您应该将数据拆分为块并并行处理它们?请参阅以下问题:

  1. terra package returns error when try to run parallel operations
  2. Process sets of rasters in parallel using lapp function from terra package

相关问题