R语言 对矩阵中的每一行元素进行排序的最快方法是什么?

o0lyfsai  于 2023-04-18  发布在  其他
关注(0)|答案(3)|浏览(170)

我有一个有几百万行和大约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)

但是对于非常大的矩阵,这种方法需要非常长的时间。
是否有不同的方法来加快行中元素的排序?

kdfy810k

kdfy810k1#

使用并行包加速

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)
6l7fqoea

6l7fqoea2#

您可以使用package 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(或其并行版本)转置矩阵。

ee7vknir

ee7vknir3#

这里有一个聪明的方法:

res <- matrix(mm[order(row(mm), -mm)], nrow = nrow(mm), byrow = TRUE)

也比别人快:

system.time(
  res <- matrix(mm[order(row(mm), -mm)], nrow=nrow(mm), byrow=TRUE)
)
 user  system elapsed
1.910   0.254   2.170

相关问题