大光栅频率表/计数

时间:2017-03-24 09:27:48

标签: r frequency raster gdal

我尝试使用freq()计算R中栅格像素值的频率/数量。 创建两个示例栅格进行比较:

    public string JSONSelect(string Json, string JsonPath)
    {

        string jsonResult = string.Empty;

        StringBuilder sb = new StringBuilder();
        StringWriter sw = new StringWriter(sb);

        using (JsonWriter json = new JsonTextWriter(sw))
        {
            json.Formatting = Newtonsoft.Json.Formatting.None;

            JToken res = JToken.Parse(Json).SelectToken(JsonPath); //http://www.newtonsoft.com/json/help/html/SelectToken.htm
            if (res != null)
            {
                switch (res.Type)
                {
                    case JTokenType.String:
                        sb.Append(((JValue)res).ToString());
                        break;
                    case JTokenType.Null:
                        break;
                    default:
                        res.WriteTo(json); //<-----------here!
                        break;
                }
            }
        }
        jsonResult = sb.ToString();
        return jsonResult;
    }

使用freq()获取像素数

library(raster)
RastSmall <- raster(nrow=70, ncol=70) 
RastBig   <- raster(nrow=7000, ncol=7000) 
set.seed(0)
RastSmall[] <- round(runif(1:ncell(r_hr), 1, 5))
RastBig[] <- round(runif(1:ncell(r_hr), 1, 5))

然而,它是一个相当大的文件,需要很长时间,即长达数小时。在R中有更快的方式吗? 这里是小型和大型栅格的速度差异:

freq(RastSmall)
value    count
[1,]     1  6540000
[2,]     2 12150000
[3,]     3 12140000
[4,]     4 11720000
[5,]     5  6450000  

有没有办法加快速度?或者可以使用像gdal tools这样的命令行来完成吗?

3 个答案:

答案 0 :(得分:0)

我上周完成了这一点,但是我无法在R中找到其他更快捷的方法。我已经尝试通过调用{{1}来使用rqgis包来做到这一点。 GRASS的。它工作但比R本机功能慢。也许你会有更好的运气。这是我的草代码,如果您想尝试它:

r.report

答案 1 :(得分:0)

不是一个惊人的保存,但如果你从你的栅格中获得值,然后运行base :: table函数,它可以节省大约20%。我的光栅是500万个细胞。

# read in raster to obtain frequency table
r <- raster("./path/myraster.tif")

# perform tests; traditional freq() vs. getValues() & table()
require(microbenchmark)
  mbm <- microbenchmark(
    Freq = {freqf <- freq(r,useNA="no"); 
            freq.df <- data.frame(CODE=freqf[,1], N=freqf[,2]},
    GetVals = {v <- getValues(r);
               vt <- table(v); 
               getval.df <- data.frame(CODE=as.numeric(names(vt)),N=as.numeric(as.matrix(vt)))},
    times=5
  )
  mbm

Unit: seconds
    expr      min       lq     mean   median       uq      max neval
    Freq 191.1649 191.8001 198.8567 192.5256 193.0986 225.6942     5
 GetVals 153.5552 154.8776 156.9173 157.0539 159.0400 160.0598     5

# check the routines have identical results
identical(freq.df,getval.df)
[1] TRUE
我猜是有点拯救 (N.B.我制作数据帧的原因是我继续处理频率分析产生的数据)

答案 2 :(得分:0)

我认为最有效的计算方法是使用GDAL中的GetHistogram( )。不幸的是,我找不到在R中使用它的方法。最接近的方法是在R中使用gdalUtilities::gdalinfo,并使用标志-hist或hist = TRUE,但将计算限制在0-255之间。 另一种选择是使用rasterDT::freqDT,它比常规选项要快。这里是一个例子:

library(gdalUtilities)
library(raster)
library(rasterDT)
library(microbenchmark)

RastBig   <- raster(nrow=7000, ncol=7000) 
set.seed(0)
RastBig[] <- round(runif(1:ncell(RastBig), 1, 5))
writeRaster(RastBig, filename = 'C:/temp/RastBig.tif')


mbm <- microbenchmark(times = 50,
  freq1 = freq(RastBig),
  freq2 = table(RastBig[]),
  freq3 = freqDT(RastBig),
  freq4 = ({
    
    gdalLog <- capture.output(gdalUtilities::gdalinfo(datasetname = 'C:/temp/RastBig.tif', hist = TRUE));
    (bucxml <- as.numeric(sub('buckets.+', '', grep('buckets ', gdalLog, value = TRUE))));
    (minxml <- as.numeric(gsub('.+from | to.+', '', grep('buckets ', gdalLog, value = TRUE)) ));
    (maxxml <- as.numeric(gsub('.+to |:', '', grep('buckets ', gdalLog, value = TRUE))));
    (histxml <- as.numeric(strsplit(split = '[[:space:]]', gsub("^ |^  ", "", gdalLog[grep('buckets', gdalLog)+1]))[[1]]));
    
    labs <- seq(from = minxml, to = maxxml, length.out = bucxml);
    df <- data.frame(labs, nwlab = c(ceiling(labs[1]),
                                      round(labs[2:(bucxml-1)]),
                                      floor(labs[bucxml])), 
                      val = histxml);
    hist <- aggregate(df$val, by = list(df$nwlab), sum)})
)

结果:

> freq1
 value    count
[1,]     1  6127755
[2,]     2 12251324
[3,]     3 12249376
[4,]     4 12248938
[5,]     5  6122607

> freq2

       1        2        3        4        5 
 6127755 12251324 12249376 12248938  6122607 

> freq3
   ID     freq
1:  1  6127755
2:  2 12251324
3:  3 12249376
4:  4 12248938
5:  5  6122607

> freq4
  Group.1        x
1       1  6127755
2       2 12251324
3       3 12249376
4       4 12248938
5       5  6122607


Unit: milliseconds
  expr          min           lq         mean       median        uq        max neval
 freq1 58628.486301 59100.539302 59400.304887 59383.913701 59650.412 60841.3975    50
 freq2 55912.170401 56663.025202 56954.032395 56919.905051 57202.001 58307.9500    50
 freq3  3785.767301  4006.858102  4288.699531  4292.447250  4536.382  4996.0598    50
 freq4     7.892201     8.883102     9.255641     9.154001     9.483    15.6072    50

编辑:使用此方法比方法3快得多

rB <- raster('C:/temp/RastBig.tif')
freq3B <- freqDT(rB)