减少大型栅格列表中马赛克的内存使用量

时间:2018-03-10 23:21:31

标签: r r-raster

我正在使用mosaic包中的raster函数,使用@RobertH here建议的方法合并一个长(11,000个文件)栅格列表。

rlist <- sapply(list_names)
rlist$fun <- mean
rlist$na.rm <- TRUE
x <- do.call(mosaic, rlist)

正如您可能想象的那样,这最终会超出我的可用内存(在几个不同的计算机和计算群集上)。我的问题是:有没有办法减少mosaicdo.call的内存使用量?我尝试在maxmemory中更改rasterOptions(),但这似乎没有帮助。以较小批量处理光栅似乎是有问题的,因为光栅可能在空间上是分离的(即,顺序光栅文件可能位于彼此非常远的位置)。提前感谢您提供任何帮助。

1 个答案:

答案 0 :(得分:5)

不是一次将所有栅格加载到内存中(在mosaic()调用中),您可以一次处理一个吗?这样,每次将一个光栅带入内存时,你的马赛克都会更新,但是你可以摆脱新的光栅并保持不断更新的马赛克光栅。

假设您的rlist对象是一个栅格列表,我想的是:

伪代码

  1. updating_raster对象初始化为列表中的第一个栅格
  2. 依次从第二个栅格
  3. 开始循环遍历列表中的每个栅格
  4. 将第i个栅格读入名为next_raster
  5. 的内存中
  6. 通过使用自身镶嵌和下一​​个使用加权平均值的栅格覆盖updating_raster对象来更新R对象
  7. mosaic()代码

    使用library(raster) r <- raster(ncol=100, nrow=100) r1 <- crop(r, extent(-10, 11, -10, 11)) r2 <- crop(r, extent(0, 20, 0, 20)) r3 <- crop(r, extent(9, 30, 9, 30)) r1[] <- 1:ncell(r1) r2[] <- 1:ncell(r2) r3[] <- 1:ncell(r3) m1 <- mosaic(r1, r2, r3, fun=mean) 帮助文件示例中的代码进行测试...

    首先生成一些栅格并使用标准镶嵌方法。

    rlist <- list(r1, r2, r3)
    

    将栅格放入列表中,使其格式与我认为的格式相似。

    NA

    由于weighted.mean()函数的updating_sum_raster <- rlist[[1]] 处理,我选择通过将求和分解为不同的步骤来创建相同的效果...

    首先初始化求和栅格:

    NA

    然后初始化&#34;计数器&#34;光栅。这将表示在每个像素上进行镶嵌的栅格数量。它在所有不是NA的单元格中以1开头。如果将非NA值添加到更新总和中,它应该正确处理updating_counter_raster <- updating_sum_raster updating_counter_raster[!is.na(updating_counter_raster)] <- 1 s,使其仅对给定像素递增。

    NA

    这里的循环并不要求所有栅格一次都在内存中。要添加到镶嵌中的栅格的计数器栅格仅在不是for (i in 2:length(rlist)) { next_sum_raster <- rlist[[i]] next_counter_raster <- next_sum_raster next_counter_raster[!is.na(next_counter_raster)] <- 1 updating_sum_raster <- mosaic(x = updating_sum_raster, y = next_sum_raster, fun = sum) updating_counter_raster <- mosaic(updating_counter_raster, next_counter_raster, fun = sum) } m2 <- updating_sum_raster / updating_counter_raster 的单元格中具有值1。通过对当前计数器栅格和更新计数器栅格求和来更新计数器。通过将当前栅格值和更新栅格值相加来更新总和。

    mosaic()

    此处的值似乎与identical(values(m1), values(m2)) > TRUE 函数

    的使用相匹配
    identical(m1, m2)
    > FALSE
    

    但是栅格本身并不相同:

    compareRaster()

    不完全确定原因,但也许这会让你更接近?

    或许compareRaster(m1, m2) > TRUE 是更好的检查方式:

    plot(m1)
    text(m1, digits = 2)
    plot(m2)
    text(m2, digits = 2)
    

    万岁!

    这是一个情节!

    mosaic()

    comparison between mosaic function and loop approach

    在杂草中多挖一点......

    来自mosaic.R文件:

    看起来v函数初始化一个名为v的矩阵,以填充列表中所有栅格中所有单元格的值。矩阵v中的行数是输出栅格中的单元格数(基于完整的镶嵌范围和分辨率),列数是在您的情况下要镶嵌的栅格数量(11,000) 。也许你在R中遇到矩阵创建的极限?

    使用1000 x 1000光栅(1e6像素)时,NA的{​​{1}}矩阵占用41 GB。你对最终的镶嵌光栅有多大的期待?

    r <- raster(ncol=1e3, nrow=1e3)
    x <- 11000
    v <- matrix(NA, nrow=ncell(r), ncol=x)
    format(object.size(v), units = "GB")
    [1] "41 Gb"