【问题标题】:Calculate sum of array cells within a given radius计算给定半径内的数组单元的总和
【发布时间】:2013-08-22 19:16:49
【问题描述】:

这个问题是在 GIS (ArcMap 10.1) 中的计算需要一个多月的时间来计算(但尚未完成)之后出现的。现在我正在尝试在 R 中找到更快的解决方案。

我有一个约 30,000 x 80,000 个单元格的矩阵,其中每个单元格代表 5x5 平方米。我需要计算每个单元格在给定半径(3000 米)内的单元格中的值的总和。 对于矩阵边缘的单元格,我假设矩阵外的值为 0。

问题是如何定义半径内的单元格。 一定有一个库有这个功能,但我找不到。

有什么建议吗?

【问题讨论】:

  • 花费一些时间我并不感到惊讶。你有 24 亿个细胞。对于 24 亿个单元中的 每个,您必须计算出其他单元中的哪些位于 3000m 范围内,然后将这些值相加。你为什么不...让它在 100m 单元的空间分辨率下工作,从而将你的处理开销减少(100/5)^2 = 400 倍作为第一个近似值,所以你知道它是有效的。如果您热衷于使用r,请查看raster::focalraster::focalWeight,但为每个单元格执行此操作仍然需要aaaaaaaaaaaaaaages
  • 距离计算并不那么棘手,假设您的坐标系中有一个规则网格 - 您实际上可以预先计算一组单元格的 x-y 偏移量。但是,如果我的数学是正确的,那么 5m 单元格上的 3000m 半径意味着 600 个单元格的半径,所以你要总结的就是 1130973 个单元格。对于您的 24 亿个细胞中的每一个。可能有一种方法,您只需考虑相邻单元格之间的增量并在窗口更改中添加/减去值...
  • 当然这也是相当尴尬的并行,所以你可以启动一个包含 1000 个 Amazon 实例的集群,然后你可能会在有生之年完成它。
  • 所以显而易见的反应是:为什么在源网格和结果网格中都需要如此惊人的精细分辨率?除非您在高空间频率区域(数据的 FFT)中获得了非常大的值,否则通过对数组进行块求和,例如 300x800 像素并对其进行操作,您可能会获得 99% 的准确度。
  • 感谢您的建议。首先澄清一下:我的栅格包含整个国家的人口密度。因此,栅格不是一个充满数据的矩形,而是由许多具有 NoData 或 0 值的像元组成(例如,在海上或跨越边界)。所以实际上我只想对包含数据的单元格运行计算,这会在 30,00 x 80,000 的矩形中留下大约一半的单元格。我正在考虑使用 !is.na 提取包含数据的单元格并对其进行迭代。

标签: r


【解决方案1】:

您可以测试的一种快速方法是使用extract 并将buffer 设置为3000m,然后在fun 参数中使用sum。您可以按顺序提取栅格中的每个像元编号。但我仍然认为这将花费大量时间。假设您的栅格名为r....

#  in the first instance I would set y to be smallish, like say 1:100 and see how long it takes
extract( r , y = 1:ncell(r) , buffer = 3000 , fun = sum )

现在,raster 包确实内置了一些并行性,通过访问大型、大型、大型多核机器可以通过运行...

beginCluster()
extract( r , y = 1:ncell(r) , buffer = 3000 , fun = sum )
endCluster()

不要忘记将extract 的输出分配给一个变量。

【讨论】:

  • @llik:在一个小例子上尝试一下,然后是一个稍微大一点的例子,然后是一个更大的例子,然后猜测完成整个事情需要多长时间。计划完成后的庆祝活动。
  • SimonO101、Spacedman 和 Carl:感谢您的建议。首先澄清一下:我的栅格由整个国家的人口密度组成。因此,栅格不是一个充满数据的矩形,而是由许多具有 NoData 或 0 值的像元组成(例如,在海上或跨越边界)。所以实际上我只想在有数据的单元格上运行计算。
  • @Ilik 所以只在值为> 0的单元格上?
  • 我用提取物尝试了 SimonO101 的解决方案,但我收到一条错误消息: .cellValues(x, y, ...) 中的错误:未使用的参数(缓冲区 = 3000,乐趣 = " sum", na.rm = TRUE) 我注意到我的栅格的值为 -1.401298e-45(这是 -Ifn 吗?),所以我尝试仅对具有数据的单元格执行相同操作,但得到了相同的错误: > Pden2007[600102000:600102003] [1] 77.98655 77.98655 77.98655 77.98655 > 测试 = 提取(Pden2007,y = 600102000:600102010,缓冲区 = 3000(,乐趣 = 'sum' 中的错误,naxrm,=TRUE) y, ...) : 未使用的参数 (buffer = 3000, fun = "sum", na.rm = TRUE)
  • @SimonO101:不,我还需要在单元格 = 0 上运行计算,因为在半径 3000m 处可能会有要求和的值
猜你喜欢
  • 1970-01-01
  • 2011-04-25
  • 2017-04-13
  • 2022-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-13
  • 2012-12-30
相关资源
最近更新 更多