【问题标题】:Operations on mult-dimensional arrays in R: apply vs data.table vs plyr (parallel)R中多维数组的操作:apply vs data.table vs plyr(并行)
【发布时间】:2014-10-16 09:12:23
【问题描述】:

在我的研究工作中,我通常处理大型 4D 数组(20-2 亿个元素)。 我正在尝试提高计算的计算速度,以寻找速度和简单性之间的最佳折衷。多亏了 SO,我已经向前迈出了一步(请参阅 herehere

现在,我正在尝试利用最新的软件包,例如 data.tableplyr

让我们从以下内容开始:

D = c(100, 1000, 8) #x,y,t
d = array(rnorm(prod(D)), dim = D)

我想为每个x(第一维)和y(第二维)获取t 高于第90 个百分位的值。让我们用基础 R 来做:

system.time(
    q1 <- apply(d, c(1,2), function(x) {
        return(x >= quantile(x, .9, names = F))
        })
)    

在我的 Macbook 上大约需要 10 秒。我得到一个数组:

> dim(q1)
[1]    8  100 1000

apply 奇怪地改变了尺寸的顺序,反正我现在不在乎)。现在我可以meltreshape2 打包)我的数组并将其用于data.table

> d_m = melt(d)
> colnames(d_m) = c('x', 'y', 't', 'value')
> d_t = data.table(d_m)

然后我做一些 data.table “魔术”:

system.time({
    q2 = d_t[,q := quantile(value, .9, names = F), by="x,y"][,ev := value > q]
})

计算现在只需不到 10 秒。现在我想试试plyrddply

system.time({
    q3 <- ddply(d_m, .(x, y), summarise, q = quantile(value, .9, names = F))
})

现在,需要 60 秒。如果我移动到dplyr,我可以在十秒内再次进行相同的计算。

但是,我的问题如下:您会如何以更快的方式进行相同的计算?如果我考虑一个更大的矩阵(比如大 20 倍),我使用 data.table wrt apply 函数获得更快的计算,但在相同的数量级(14 分钟对 10 分钟)。 任何评论都非常感谢......

编辑

我已经使用Rcpp 在 c++ 中实现了分位数函数,将计算速度提高了八倍。

【问题讨论】:

  • 我怀疑你的瓶颈是quantile 而不是用于“split-apply-combine”的函数。分析您的代码。可能您需要编写一个更快的 quantile 函数(它目前在 R 中实现,因此速度不是很快)。看看 Rcpp。
  • 你是对的。我刚刚花了一个小时来学习如何使用 Rcpp 复制 R 分位数算法。我已经获得了八倍的加速。

标签: r multidimensional-array data.table plyr


【解决方案1】:

正如@roland 所建议的,加快代码速度的一种可能解决方案是实现更快版本的quantile 函数。我花了一个小时来学习如何使用Rcpp 来做到这一点,运行时间减少了八倍。我已经实现了分位数算法的type 7 版本(默认选择)。 我们距离 MATLAB 的性能还很远(讨论了here),但在我的情况下,这是一个令人印象深刻的进步。到目前为止,我对自己编写的 Rcpp 代码并不感到自豪,我没有时间打磨它。无论如何,它可以工作(我用 R 函数检查了结果),所以如果你有兴趣,可以从 here 下载它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-31
    • 1970-01-01
    • 1970-01-01
    • 2018-04-03
    • 1970-01-01
    • 2021-09-14
    • 1970-01-01
    相关资源
    最近更新 更多