在我的研究工作中,我通常会处理大型4D阵列(20-200万个元素)。 我正在努力提高计算的计算速度,寻求速度和简单性之间的最佳平衡。由于SO(见here和here)
,我已经向前迈进了一步现在,我正在尝试利用data.table
和plyr
这样的最新软件包。
让我们从以下内容开始:
D = c(100, 1000, 8) #x,y,t
d = array(rnorm(prod(D)), dim = D)
我想为每个x
(第一维度)和y
(第二维度)获取超过第90个百分位数的t
的值。让我们用基数R来做:
system.time(
q1 <- apply(d, c(1,2), function(x) {
return(x >= quantile(x, .9, names = F))
})
)
在我的Macbook上大约十秒钟。我得到一个数组:
> dim(q1)
[1] 8 100 1000
(apply
奇怪地改变了维度的顺序,反正我现在不在乎)。现在我可以melt
(reshape2
包)我的数组并将其用于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秒。现在我想试试plyr
和ddply
:
system.time({
q3 <- ddply(d_m, .(x, y), summarise, q = quantile(value, .9, names = F))
})
现在需要60秒。如果我转到dplyr
我可以在十秒内再次进行相同的计算。
但是,我的问题如下:如何以更快的方式进行相同的计算?如果我考虑一个更大的矩阵(比如说大20倍),我可以使用data.table获得更快的计算{。{1}}函数,但是在相同的数量级(14分钟对10分钟)。 任何评论都非常感谢...
修改
我使用apply
在c ++中实现了分位数函数,加快了八次计算速度。