【问题标题】:raster package taking all hard drive光栅包占用所有硬盘
【发布时间】:2014-10-15 02:11:13
【问题描述】:

我正在处理栅格的时间序列(modis ndvi 图像)来计算该系列的平均值和标准偏差。每个年度系列由 23 个 ndvi.tif 图像组成,每个 508Mb,因此总共需要处理 11Gb。以下是一年的脚本。我必须重复这几年。

library(raster)
library("rgeos")
filesndvi <- list.files(, pattern="NDVI.tif",full.names=TRUE) 
filesetndvi10 <- stack(filesndvi)
names(filesetndvi10)
avgndvi10<-mean(filesetndvi10)
desviondvi10 <- filesetndvi10 - avgndvi10
sumdesvioc <-sum(desviondvi10^2)
varndvi10  <- sumdesvioc/nlayers(filesetndvi10)
sdndvi10  <- sqrt(varndvi10)
cvndvi10  <- sdndvi10/avgndvi10

问题: 该过程会在硬盘驱动器中累积写入,直到写满为止。不知道该过程在HD中的哪个位置写入。清理我发现的 HD 的唯一方法是重新启动。试过rm,没用。尝试关闭 RStudio,没有用。我在 4Gb RAM Asus UX31 和 256Gb HD 上使用 R 3.0.2 和 RStudio 0.98.994 和 Ubuntu 14.04。任何在计算每年而不重新启动的情况下清理 HD 的想法都将受到欢迎。谢谢

【问题讨论】:

  • 最有可能tempdir()

标签: r raster


【解决方案1】:

还有两件事需要考虑。首先,通过组合计算或覆盖函数中的步骤来减少中间文件(这里没有太多的范围,但有一些),这也可以加快计算,因为从磁盘读取和写入磁盘的次数会减少。其次,控制删除特定文件。在 calc 和 overlay 函数中,您可以提供文件名,以便您可以删除不再需要的文件。但您也可以显式删除临时文件。首先删除指向这些文件的对象当然是个好习惯。这是一个基于你的例子。

library(raster)
# example data
set.seed(0)
ndvi <- raster(nc=10, nr=10)
n1 <- setValues(ndvi, runif(100) * 2 - 1)
n2 <- setValues(ndvi, runif(100) * 2 - 1)
n3 <- setValues(ndvi, runif(100) * 2 - 1)
n4 <- setValues(ndvi, runif(100) * 2 - 1)
filesetndvi10 <- stack(n1, n2, n3, n4)

nl <- nlayers(filesetndvi10)
avgndvi10 <- mean(filesetndvi10)
desviondvi10_2 <- overlay(filesetndvi10, avgndvi10, fun=function(x, y) (x - y)^2 , filename='over_tmp.grd')
sdndvi10 <- calc(desviondvi10_2, fun=function(x) sqrt(sum(x) / nl), filename='calc_tmp.grd')
cvndvi10  <- overlay(xsdndvi10, avgndvi10, fun=function(x,y) x / y, filename='cvndvi10.grd', overwrite=TRUE)

f <- filename(avgndvi10)
rm(avgndvi10, desviondvi10_2, sdndvi10)
file.remove(c(f, extension(f, '.gri')))
file.remove(c('over_tmp.grd', 'over_tmp.gri', 'calc_tmp.grd', 'calc_tmp.gri'))

要找出临时文件的写入位置来查看

rasterOptions()

或将路径作为变量获取:

dirname(rasterTmpFile()) 

要设置路径,请使用

rasterOptions(tmpdir='a path')

【讨论】:

  • rasterOptions(tempdir='a path') 应该是 rasterOptions(tmpdir='a path')
【解决方案2】:

我也遇到了同样的问题,但有一些技巧可以提供帮助。 首先是获得更多内存。 Ram 和 HD 空间很便宜,并且在处理大型 R 对象(如栅格)时会产生巨大的影响。 其次,在光栅包中使用removeTmpFiles()。您可以将其设置为删除超过一定小时数的 tmp 文件。例如removeTmpFiles(0.5) 将删除超过 30 分钟的 tmp 文件。确保仅在将不再调用文件的时间设置此设置。 第三,使用类似rasterOptions() 的以下片段。小心设置内存块大小;这些不适用于您的系统,但您可能会发现比默认设置更优化的东西。 最后,在烹饪时使用rm()gc() 进行清洁。希望这会有所帮助,但如果您找到更好的解决方案,请告诉我。

tmpdir_name <- paste(c(drive, ":/RASTER_TEMP/"), collapse='')
if(file.exists(tmpdir_name) == FALSE){
    dir.create(tmpdir_name)
}

rasterOptions(datatype = "FLT4S", 
    progress = "text", 
    tmpdir = tmpdir_name, 
    tmptime = 4, 
    timer = TRUE,
    tolerance = 0.5,
    chunksize = 1e+08,
    maxmemory = 1e+09)

【讨论】:

  • 非常感谢ecos先生。我将删除临时文件。我发现它们位于 /tmp/R_raster_myuser 中。是的,我肯定会购买更多的 RAM,或者可能是一台并行计算机。干杯
  • 关闭问题。我已经使用 rasterOptions(tmpdir="path") 将临时文件定向到 3Tb 外部驱动器解决了我的问题。不是最优雅的解决方案,但它确实有效。
  • 不确定您最后的评论:将临时文件写入外部磁盘可能会使您的计算速度变慢。只需使用上面的命令每隔一段时间删除您的临时文件就可以了。
  • 同意@lucas,你必须小心。当我没有多少选择时,我会确保使用 USB 3.0 和 SSD 或速度非常快的驱动器。但是,如果您只有一个选择并且它不是连接到系统总线的驱动器,那么由于累积的读/写时间,预计分析速度会变慢。尽管速度较慢,但​​它仍然可以解决空间问题。
  • 感谢 cmets。计算速度相当合理,虽然不是我非常关心的问题。外部 HD 通过 USB 3.0 连接。手动删除临时文件意味着我必须观察这个过程。在外部 HD 中写入临时文件让我摆脱了这项工作。
【解决方案3】:

利用this answer,我找到了另一种更适合我的方法来解决这个问题。就我而言,我正在使用并行循环并且不想从临时目录中删除所有文件,因为它可能会删除其他进程的临时文件。

@RobertH 的回答建议命名每个单独的临时文件名很好,但我不确定是否手动强制光栅将小文件写入硬盘驱动器而不是使用 RAM 并减慢进程(光栅文档说如果文件不适合 RAM,它只会写入磁盘)。

所以,我所做的是从循环或并行进程中创建一个临时目录,该目录与循环中正在处理的数据的唯一名称相关联,在我的情况下,single@data$OWNER 的值:

#creates unique filepath for temp directory
dir.create (file.path("c:/",single@data$OWNER), showWarnings = FALSE)

#sets temp directory
rasterOptions(tmpdir=file.path("c:/",single@data$OWNER)) 

在此处插入您的处理代码,然后在循环结束时删除整个文件夹:

#removes entire temp directory without affecting other running processes
unlink(file.path("c:/",single@data$OWNER), recursive = TRUE)

【讨论】:

    【解决方案4】:

    我注意到在 RobertH 有用的答案中,最后一个建议的命令有一个额外的“e”。应该是
    rasterOptions(tmpdir='a path')

    而不是
    rasterOptions(tempdir='a path')

    【讨论】:

      【解决方案5】:

      也许这很明显,但我发现在此线程中实施建议的另一个技巧是要小心处理指令的顺序。尽量避免批量执行相同的指令并“事后清理”。雾化代码并清理小块。例如,而不是(从上面):

      [...]
      nl <- nlayers(filesetndvi10)
      avgndvi10 <- mean(filesetndvi10)
      
      desviondvi10_2 <- overlay(filesetndvi10, avgndvi10, fun=function(x, y) (x - y)^2 , 
      filename='over_tmp.grd')
      sdndvi10 <- calc(desviondvi10_2, fun=function(x) sqrt(sum(x) / nl), filename='calc_tmp.grd')
      cvndvi10  <- overlay(xsdndvi10, avgndvi10, fun=function(x,y) x / y, filename='cvndvi10.grd', overwrite=TRUE)
      
      f <- filename(avgndvi10)
      rm(avgndvi10, desviondvi10_2, sdndvi10)
      file.remove(c(f, extension(f, '.gri')))
      file.remove(c('over_tmp.grd', 'over_tmp.gri', 'calc_tmp.grd', 'calc_tmp.gri'))
      

      这将需要更少的 RAM 和驱动器空间:

      [...]
      nl <- nlayers(filesetndvi10)
      avgndvi10 <- mean(filesetndvi10)
      
      desviondvi10_2 <- overlay(filesetndvi10, avgndvi10, fun=function(x, y) (x - y)^2 , 
      filename='over_tmp.grd')
      rm(avgndvi10)
      file.remove(c('over_tmp.grd', 'over_tmp.gri'))
      
      sdndvi10 <- calc(desviondvi10_2, fun=function(x) sqrt(sum(x) / nl), filename='calc_tmp.grd')
      rm(desviondvi10_2)
      file.remove(c('calc_tmp.grd', 'calc_tmp.gri'))
      
      cvndvi10  <- overlay(xsdndvi10, avgndvi10, fun=function(x,y) x / y, filename='cvndvi10.grd', overwrite=TRUE)
      rm(sdndvi10)
      file.remove(c('cvndvi10.grd', 'cvndvi10.gri'))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-01-10
        • 2015-01-05
        • 1970-01-01
        • 2015-03-19
        • 2015-03-24
        • 1970-01-01
        • 2012-07-10
        相关资源
        最近更新 更多