1

tl;博士:为什么 raster::sampleRandom 需要这么多时间?例如从 30k 个细胞中提取 3k 个细胞(超过 10k 个时间步)。我能做些什么来改善这种情况吗?
编辑:底部的解决方法。

考虑一个 R 脚本,我必须在其中读取一个大文件(通常超过 2-3GB)并对数据执行分位数计算。我使用 raster 包来读取 ( netCDF) 文件。我在 64 位 GNU/Linux 下使用 R 3.1.2 和 4GB 的 RAM,大部分时间都有 3.5GB 可用。

由于文件通常太大而无法放入内存(由于某种原因,即使 2GB 的文件也无法放入 3GB 的可用内存:)unable to allocate vector of size 2GB我不能总是这样做,如果我有 16GB 的 RAM,我会这样做:

pr <- brick(filename[i], varname=var[i], na.rm=T)
qs <- quantile(getValues(pr)*gain[i], probs=qprobs, na.rm=T, type=8, names=F)

sampleRaster()但相反,我可以使用包中的函数对文件中的少量单元格进行采样raster,仍然可以获得良好的统计数据。
例如:

pr <- brick(filename[i], varname=var[i], na.rm=T)
qs <- quantile(sampleRandom(pr, cnsample)*gain[i], probs=qprobs, na.rm=T, type=8, names=F)

我对 6 个不同的文件(i从 1 到 6 个)执行此操作,这些文件都有大约 30k 个单元和 10k 个时间步长(所以 300M 值)。文件是:

  1. 1.4GB,1 个变量,文件系统 1
  2. 2.7GB,2 个变量,所以我读取的变量大约 1.35GB,文件系统 2
  3. 2.7GB,2 个变量,所以我读取的变量大约 1.35GB,文件系统 2
  4. 2.7GB,2 个变量,所以我读取的变量大约 1.35GB,文件系统 2
  5. 1.2GB,1 个变量,文件系统 3
  6. 1.2GB,1 个变量,文件系统 3

注意:

  1. 文件位于三个不同的 nfs 文件系统上,我不确定它们的性能。我不能排除这样一个事实,即 nfs 文件系统的性能从一个时刻到另一个时刻可能会有很大差异。
  2. 脚本运行时,RAM 使用率始终为 100%,但系统并未使用所有的交换空间。
  3. sampleRandom(dataset, N)从一层(=一个时间步长)获取 N 个非 NA 随机单元,并读取它们的内容。对每一层的相同 N 个单元执行此操作。如果将数据集可视化为 3D 矩阵,Z 为时间步长,则该函数采用 N 个随机非 NA 列。但是,我猜该函数不知道所有层的 NA 都位于相同的位置,因此它必须检查它选择的任何列中是否没有 NA。
  4. 当对具有 8393 个单元(总共约 340MB)的文件使用相同的命令并读取所有单元时,计算时间是尝试从具有 30k 个单元的文件中读取 1000 个单元的一小部分。

产生下面输出的完整脚本在这里,带有注释等。


如果我尝试读取所有30k 个单元格

  1. cannot allocate vector of size 2.6 Gb

如果我阅读1000 个单元格

  1. 5分钟
  2. 45米
  3. 30米
  4. 30米
  5. 20米
  6. 20米

如果我阅读3000 个单元格

  1. 15分钟
  2. 18米
  3. 35米
  4. 34 米
  5. 60米
  6. 60米

如果我尝试读取5000 个单元格

  1. 2.5 小时
  2. 22 小时
  3. 对于 >2 我不得不在 18 小时后停下来,我不得不将工作站用于其他任务

通过更多的测试,我已经能够发现它是sampleRandom()占用大部分计算时间的函数,而不是分位数的计算(我可以使用其他分位数函数来加速,例如kuantile())。

  1. 为什么sampleRandom()要花这么长时间?为什么它的表现如此奇怪,有时很快有时很慢?
  2. 最好的解决方法是什么?我想我可以为第一层手动生成 N 个随机单元,然后raster::extract为所有时间步手动生成。

编辑:工作解决方法是:

cells <- sampleRandom(pr[[1]], cnsample, cells=T) #Extract cnsample random cells from the first layer, exluding NAs
cells[,1]
prvals <- pr[cells[,1]] #Read those cells from all layers
qs <- quantile(prvals, probs=qprobs, na.rm=T, type=8, names=F) #Compute quantile

这很有效,而且速度非常快,因为所有层的 NA 都在相同的位置。我认为这应该是一个sampleRandom()可以实施的选项。

4

0 回答 0