2015-11-09 72 views
2

我正在處理大型光柵堆棧,我需要重新採樣並剪輯它們。 我讀的TIFF文件列表,並創建堆棧:如何提高處理大型柵格堆棧的R處理速度?

files <- list.files(path=".", pattern="tif", all.files=FALSE, full.names=TRUE) 
s <- stack(files) 
r <- raster("raster.tif") 
s_re <- resample(s, r,method='bilinear') 
e <- extent(-180, 180, -60, 90) 
s_crop <- crop(s_re, e) 

這個過程需要數天才能完成!但是,使用ArcPy和python會快得多。我的問題是:爲什麼R的過程如此緩慢以及是否有加速過程的方法? (我用雪包進行並行處理,但這也沒有幫助)。 這些rs層:

> r 
class  : RasterLayer 
dimensions : 3000, 7200, 21600000 (nrow, ncol, ncell) 
resolution : 0.05, 0.05 (x, y) 
extent  : -180, 180, -59.99999, 90.00001 (xmin, xmax, ymin, ymax) 
coord. ref. : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0 

> s 
class  : RasterStack 
dimensions : 2160, 4320, 9331200, 365 (nrow, ncol, ncell, nlayers) 
resolution : 0.08333333, 0.08333333 (x, y) 
extent  : -180, 180, -90, 90 (xmin, xmax, ymin, ymax) 
coord. ref. : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0 
+2

很難評論什麼可能導致這種情況,而無需掌握光柵文件。也就是說,我偶爾使用由[** gdalUtils **]封裝的GDAL函數來加速柵格操作(https://cran.r-project.org/web/packages/gdalUtils/index.html )。在這裏,我可能使用['gdal_translate()'](http://www.gdal.org/gdal_translate.html),通過它的'-tr'參數設置分辨率,並通過'-r'參數設置所需的重採樣算法。不知道它如何處理'RasterStack',但它應該處理'RasterLayer's(或者,我猜,'* .tif *'磁盤上的文件)就好了。 –

+1

確保您使用最新版本的光柵,因爲'resample'的速度最近有了很大提高(可能還不夠)。如果您顯示節目和r以便我們可以看到正在發生的事情,我也會很有幫助。對於多核,你可以嘗試beginCluster等 – RobertH

+0

@ JoshO'Brien謝謝,我會嘗試gdal,但光柵會更方便。 –

回答

3

我第二@ JoshO'Brien的建議直接使用GDAL和gdalUtils使得這個簡單。

下面是一個使用與您的尺寸相同的雙精度網格的示例。對於10個文件,我的系統需要55秒。它線性地擴展,所以你可以在365個文件中查看大約33分鐘。

library(gdalUtils) 
library(raster) 

# Create 10 rasters with random values, and write to temp files 
ff <- replicate(10, tempfile(fileext='.tif')) 
writeRaster(stack(replicate(10, { 
    raster(matrix(runif(2160*4320), 2160), 
     xmn=-180, xmx=180, ymn=-90, ymx=90) 
})), ff, bylayer=TRUE) 

# Define clipping extent and res 
e <- bbox(extent(-180, 180, -60, 90)) 
tr <- c(0.05, 0.05) 

# Use gdalwarp to resample and clip 
# Here, ff is my vector of tempfiles, but you'll use your `files` vector 
# The clipped files are written to the same file names as your `files` 
# vector, but with the suffix "_clipped". Change as desired. 
system.time(sapply(ff, function(f) { 
    gdalwarp(f, sub('\\.tif', '_clipped.tif', f), tr=tr, r='bilinear', 
      te=c(e), multi=TRUE) 
})) 

## user system elapsed 
## 0.34 0.64 54.45 

可以進一步與parallelise,例如,parLapply

library(parallel) 
cl <- makeCluster(4) 
clusterEvalQ(cl, library(gdalUtils)) 
clusterExport(cl, c('tr', 'e')) 

system.time(parLapply(cl, ff, function(f) { 
    gdalwarp(f, sub('\\.tif', '_clipped.tif', f), tr=tr, 
      r='bilinear', te=c(e), multi=TRUE) 
})) 

## user system elapsed 
## 0.05 0.00 31.92 

stopCluster(cl) 

在32秒,持續10個網格(使用4個同步過程),你正在尋找在約20分鐘的時間365頁的文件。實際上,它應該比這更快,因爲兩個線程最終可能什麼都不做(10不是4的倍數)。

+0

謝謝!這工作正常,但如果我用它來讀取所有文件,我得到內存錯誤;而光柵,你沒有這個問題。你有什麼建議嗎? –

+0

@DNM哪部分導致內存錯誤? – jbaums

+0

parLapply/sapply會這樣做。 –

1

爲了便於比較,這是我得到:

library(raster) 
r <- raster(nrow=3000, ncol=7200, ymn=-60, ymx=90) 
s <- raster(nrow=2160, ncol=4320) 
values(s) <- 1:ncell(s) 
s <- writeRaster(s, 'test.tif') 

x <- system.time(resample(s, r, method='bilinear')) 
# user system elapsed 
# 15.26 2.56 17.83 

10個文件需要150秒。所以我預計365個文件需要1.5小時 - 但我沒有嘗試。

+0

令人驚訝的是它在我的機器上變慢了。 '用戶系統已用完 20.45 5.22 25.75' –