R中的性能:对矩阵中的行元素进行排序的最快方法是啥?
Posted
技术标签:
【中文标题】R中的性能:对矩阵中的行元素进行排序的最快方法是啥?【英文标题】:Performance in R: What is the fastest way to sort the elements of a row in a matrix?R中的性能:对矩阵中的行元素进行排序的最快方法是什么? 【发布时间】:2016-05-10 14:41:12 【问题描述】:我有一个包含几百万行和大约 40 列的矩阵。
我想对每一行中的元素进行排序,使它们的值递减。因此,每行中值最高的元素应该在第一列。
为此,我可以使用apply
函数。例如:
set.seed(1)
mm <- replicate(10, rnorm(20)) #random matrix with 20 rows and 10 columns
mm.sorted <- apply(mm,1,sort,decreasing=T)
但是当我对一个非常大的矩阵执行此操作时,这种方法需要很长时间。
我想知道是否有不同的方法可以加快行中元素的排序。
【问题讨论】:
您可以在此处查看并行化指南:cran.r-project.org/web/views/HighPerformanceComputing.html 我猜它看起来像lapply(split(mm, row(mm)), sort)
但将 lapply
替换为一些变体,例如 mclapply
仅供参考 - replicate(10, rnorm(20))]
是 20 行 10 列的矩阵。
@rbm:谢谢!修好了。
【参考方案1】:
你可以使用包data.table:
set.seed(1)
mm <- matrix(rnorm(1000000*40,0,10),ncol=40)
library(data.table)
system.time(
d <- as.data.table(mm)
d[, row := .I]
d <- melt(d, id.vars = "row") #wide to long format
setkey(d, row, value) #sort
d[, variable := paste0("V", ncol(mm):1)] #decreasing order
#back to wide format and coerce to matrix
msorted <- as.matrix(dcast(d, row ~ variable)[, row := NULL])
)
#user system elapsed
#4.96 0.59 5.62
如果您可以将其保留为长格式 data.table(即,跳过最后一步),在我的机器上大约需要 2 秒。
作为比较,@qjgods 在我的机器上的回答时间:
#user system elapsed
#3.71 2.08 8.81
请注意,使用apply
(或其并行版本)会转置矩阵。
【讨论】:
我不知道 reshape2:::melt.matrix 的优化程度如何,但这可能是前几个步骤的另一种选择,例如d = melt(mm); setDT(d, key=c("row","value"))
。并且可能有一个acast
或返回的东西
这是一个非常好的解决方案。但是,尽管我多次检查代码,但我无法理解 setkey 如何对其进行排序以及 dcast 如何将其转换回宽格式。你能解释一下或推荐一个教程吗?
这就是设置密钥的真正含义:对数据进行排序并将其标记为已排序。查看 setkey 和 dcast 的文档。【参考方案2】:
使用并行包加速
library(parallel)
data<-matrix(rnorm(1000000*40,0,10),ncol=40)
cl <- makeCluster(8) # 8 is the number of CPU
system.time(
parApply(cl,data,1,sort,decreasing=T)
)
user system elapsed
9.68 10.11 29.87
stopCluster(cl)
【讨论】:
以上是关于R中的性能:对矩阵中的行元素进行排序的最快方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章