【问题标题】:R: fastest way to convert matrix to colour raster using given colour lookup tableR:使用给定颜色查找表将矩阵转换为颜色栅格的最快方法
【发布时间】:2018-06-15 21:14:12
【问题描述】:

我正在寻找 R(或 Rcpp)中将给定的双精度矩阵(值介于 0 和 1 之间)转换为具有十六进制颜色代码的图像光栅的最快方法。

目前我正在做的是

library(RColorBrewer)
cols=colorRampPalette(RColorBrewer::brewer.pal(11, "RdYlBu"))(1080)
colfun=colorRamp(RColorBrewer::brewer.pal(11, "RdYlBu"))
mat=matrix(seq(1:1080)/1080,ncol=1920,nrow=1080,byrow=FALSE)
system.time(rastmat <- as.raster(apply(mat, 2, function (col) rgb(colfun(col),max=255)))) # 2.55s

但这对我的应用程序来说太慢了(我希望能够在 0.1 秒内完成)。有人知道如何有效地做到这一点吗?使用颜色函数colfun 或使用cols 作为(哈希?)查找表或类似的东西(在将数据矩阵合并为cols 的长度之后)(以更快者为准)...

稍后将使用

显示光栅
library(grid)
system.time(grid.raster(rastmat,interpolate=FALSE)) # 0.2s

【问题讨论】:

  • 您可以使用 foreach()mclapply() 来并行化您的 apply 函数。这实际上取决于操作系统和可用内核的数量
  • 你的 R 版本和你的 CPU 是什么?您的代码在我的计算机(R 3.4、Intel core i7、Linux)上运行时间为 0.6 秒
  • Ha Intel core i7 和 R 3.4.0 但 Win 8.1。所以 mclapply() 不会是一个选项 - 我想 Rcpp 和 OpenMP 的多线程是最有效的,认为下面的解决方案已经相当高效......

标签: r graphics colors rcpp raster


【解决方案1】:

使用调色板的离散化并预先计算颜色,我可以以 10 倍的速度完成任务。考虑到您的代码在我的计算机上运行 0.5 秒(而不是您评论中的 2.55 秒),我在 ~0.05 秒内执行您的任务

ncol = 100
colfun = colorRamp(RColorBrewer::brewer.pal(11, "RdYlBu"))
col = rgb(colfun(seq(0,1, length.out = ncol)), max = 255)

val2hexa = function(mat, col)
{
  idx = findInterval(mat, seq(0, 1, length.out = length(col)))
  colors = col[idx]
  rastmat = as.raster(matrix(colors, ncol = ncol(mat), nrow = nrow(mat), byrow = FALSE))
  return(rastmat)
}

rastmat <- val2hexa(mat, col)

这里是基准

microbenchmark::microbenchmark(
  orig = as.raster(apply(mat, 2, function (col) rgb(colfun(col),max=255))),
  new = val2hexa(mat, col), 
  times = 25)

Unit: milliseconds
 expr       min       lq      mean    median        uq      max neval
 orig 456.36900 466.7336 516.96512 489.52481 560.94217 618.1538    25
  new  49.10714  56.0333  65.29669  57.32988  60.16575 155.7042    25

编辑

你可以像那样获得几毫秒

val2hexa = function(mat, col)
{
  idx = findInterval(mat, seq(0, 1, length.out = length(col)))
  colors = col[idx]
  dim(colors) <- dim(mat)
  rastmat = as.raster(colors)
  return(rastmat)
}

【讨论】:

  • 非常感谢 - 有 10 000 种颜色(这是我需要的),我得到了 0.07 秒的时间,所以这应该足够好了!我仍然会稍等片刻接受您的回答,以防其他人可能仍然想出更快的东西,例如使用哈希表,blog.dominodatalab.com/… 或一些 Rcpp+OpenMP 解决方案....
  • 虽然使用 100 000 种颜色,但我的机器上的时间会下降到 0.16 秒....
  • findInterval 使用快速的内部 C 代码。然后我使用向量中的索引访问颜色。您不能期望使用哈希表更快地访问颜色。而且你不能并行化这个已经很快的任务。此外,代码中比较慢的是as.raster(matrix(...)
  • 哈,是的,我明白了 - 如果需要更快的性能,那么 as.raster() 将是一个值得关注的对象......谢谢让我知道!
  • 哈刚刚注意到 as.raster() 并不是真正需要的,因为它已经是一个十六进制颜色代码的矩阵,它所要做的就是转置,所以我们可以做 mat=matrix (seq(1:1080)/1080,nrow=1920,ncol=1080,byrow=TRUE) 在你的函数中 rastmat = matrix(colors, ncol = nrow(mat), nrow = ncol(mat), byrow = TRUE) ;class(rastmat)="raster"
猜你喜欢
  • 2012-11-06
  • 2018-10-12
  • 2015-08-18
  • 1970-01-01
  • 2018-01-09
  • 2013-08-01
  • 2018-11-09
  • 2021-11-20
  • 2016-05-12
相关资源
最近更新 更多