R 从矩阵中的每一列获取最小值的最快方法?

R 从矩阵中的每一列获取最小值的最快方法?,r,matrix,benchmarking,min,R,Matrix,Benchmarking,Min,从矩阵中的每列中提取最小值的最快方法是什么 编辑: 将所有基准移至下面的答案 使用高、短或宽矩阵: 测试数据 种子(1) matrix.inputssos软件包非常适合回答这类问题 library("sos") findFn("colMins") library("matrixStats") ?colMins 奇怪的是,在我尝试的一个例子中,colMins的速度较慢。也许有人能指出我的例子有什么好笑之处 set.seed(101); z <- matrix(runif(1e6),nr

从矩阵中的每列中提取最小值的最快方法是什么


编辑: 将所有基准移至下面的答案

使用高、短或宽矩阵: 测试数据 种子(1)
matrix.inputssos软件包非常适合回答这类问题

library("sos")
findFn("colMins")
library("matrixStats")
?colMins

奇怪的是,在我尝试的一个例子中,
colMins
的速度较慢。也许有人能指出我的例子有什么好笑之处

set.seed(101); z <- matrix(runif(1e6),nrow=1000)
library(rbenchmark)
benchmark(colMins(z),apply(z,2,min))
##               test replications elapsed relative user.self sys.self
## 2 apply(z, 2, min)          100  14.290     1.00     7.216    7.057
## 1       colMins(z)          100  25.585     1.79    15.509    9.852

set.seed(101);z这里有一个在正方形和宽矩阵上更快的方法。它在矩阵的行上使用
pmin
。(如果您知道将矩阵拆分为行的更快方法,请随意编辑)

使用与@RicardoSaporta相同的基准:

$`Square Matrix`
          test elapsed relative
3 pmin.on.rows   1.370    1.000
1          apl   1.455    1.062
2         cmin   2.075    1.515

$`Wide Matrix`
      test elapsed relative
3 pmin.on.rows   0.926    1.000
2         cmin   2.302    2.486
1          apl   5.058    5.462

$`Tall Matrix`
          test elapsed relative
1          apl   1.175    1.000
2         cmin   2.126    1.809
3 pmin.on.rows   5.813    4.947

下面是迄今为止的一系列答案。这将随着更多答案的提供而更新

基准
库(rbenchmark)
图书馆(matrixStats)#供科尔明斯使用
测试列表更新2014-12-17:

colMins()
等在最新版本的。下面是使用matrixStats 0.12.2更新的基准概要,显示它(“cmin”)比第二快的方法快约5-20倍:

$`Square Matrix`
     test elapsed relative
2    cmin   0.216    1.000
1     apl   4.200   19.444
5 pmn.int   4.604   21.315
4     pmn   5.136   23.778
3    lapl  12.546   58.083

$`Tall Matrix`
     test elapsed relative
2    cmin   0.262    1.000
1     apl   3.006   11.473
5 pmn.int  18.605   71.011
3    lapl  22.798   87.015
4     pmn  27.583  105.279

$`Wide-short Matrix`
     test elapsed relative
2    cmin   0.346    1.000
5 pmn.int   3.766   10.884
4     pmn   3.955   11.431
3    lapl  13.393   38.708
1     apl  19.187   55.454

$`Wide-tall Matrix`
     test elapsed relative
2    cmin   5.591    1.000
5 pmn.int  39.466    7.059
4     pmn  40.265    7.202
1     apl  67.151   12.011
3    lapl 158.035   28.266

$`Tiny Sq Matrix`
     test elapsed relative
2    cmin   0.011    1.000
5 pmn.int   0.135   12.273
4     pmn   0.178   16.182
1     apl   0.202   18.364
3    lapl   0.269   24.455
2013年10月9日之前的评论:

仅供参考,自matrixStats v0.8.7(2013-07-28)以来,
colMins()
的速度大约是以前的两倍。原因是之前使用的函数是
colRanges()
,这解释了此处报告的“异常缓慢”的结果。同样的速度出现在
colMaxs()
rowMins()
rowMaxs()
mat[(1:ncol(mat)-1)*nrow(mat)+max.col(t(-mat))]
看起来相当快,而且是基本的R.

两个很好的答案合一!!谢谢你,本。。。有趣。我有一个5 k+列的矩阵,但只有10行。当我尝试5k+行时,apply现在是fasterI,我看不出为什么它们的排序方式与列和我的小测试的排序方式不一样,“正确排序”,并提供一个反例。基准测试总是得到我的+1。我认为你应该将这些内容作为答案,而不是作为问题的一部分(我投赞成票!)附言:我想你甚至可以用它的“内部”版本
pmin.int
替换
pmin
,以提高速度。非常感谢!
pmin
正是我最初寻找的函数。我知道这样一个函数必须存在,但找不到它。嗯,几乎完全正确——正是pmin与do.call.lappy builded into现在,HenrikB中的
更新2014-12-17
使
cmin
解决方案成为最快的解决方案。这个wiki需要更新。另外,@tennenrishin answer可能会提供更快的
base::max.col
解决方案
do.call(pmin, lapply(1:nrow(mat), function(i)mat[i,]))
$`Square Matrix`
          test elapsed relative
3 pmin.on.rows   1.370    1.000
1          apl   1.455    1.062
2         cmin   2.075    1.515

$`Wide Matrix`
      test elapsed relative
3 pmin.on.rows   0.926    1.000
2         cmin   2.302    2.486
1          apl   5.058    5.462

$`Tall Matrix`
          test elapsed relative
1          apl   1.175    1.000
2         cmin   2.126    1.809
3 pmin.on.rows   5.813    4.947
  library(rbenchmark)
  library(matrixStats)  # for colMins


  list.of.tests <- list (
        ## Method 1: apply()  [original]
        apl =expression(apply(mat, 2, min, na.rm=T)),

        ## Method 2:  matrixStats::colMins [contributed by @Ben Bolker ]
        cmin = expression(colMins(mat)),

        ## Method 3: lapply() + split()  [contributed by @DWin ]
        lapl = expression(lapply( split(mat, rep(1:dim(mat)[1], each=dim(mat)[2])), min)),

        ## Method 4: pmin() / pmin.int()  [contributed by @flodel ]
        pmn = expression(do.call(pmin, lapply(1:nrow(mat), function(i)mat[i,]))),
        pmn.int = expression(do.call(pmin.int, lapply(1:nrow(mat), function(i)mat[i,]))) #,

        ## Method 5: ????
        #  e5 = expression(  ???  ),
        )  


  (times <- 
        lapply(matrix.inputs, function(mat)
            do.call(benchmark, args=c(list.of.tests, replications=500, order="relative"))[, c("test", "elapsed", "relative")]
  ))



  ############################# 
  #$         RESULTS         $#
  #$_________________________$#
  #############################

  # $`Square Matrix`
  #      test elapsed relative
  # 5 pmn.int   2.842    1.000
  # 4     pmn   3.622    1.274
  # 1     apl   3.670    1.291
  # 2    cmin   5.826    2.050
  # 3    lapl  41.817   14.714  

  # $`Tall Matrix`
  #      test elapsed relative
  # 1     apl   2.622    1.000
  # 2    cmin   5.561    2.121
  # 5 pmn.int  11.264    4.296
  # 4     pmn  18.142    6.919
  # 3    lapl  48.637   18.550  

  # $`Wide-short Matrix`
  #      test elapsed relative
  # 5 pmn.int   2.909    1.000
  # 4     pmn   3.018    1.037
  # 2    cmin   6.361    2.187
  # 1     apl  15.765    5.419
  # 3    lapl  41.479   14.259  

  # $`Wide-tall Matrix`
  #      test elapsed relative
  # 5 pmn.int  20.917    1.000
  # 4     pmn  26.188    1.252
  # 1     apl  38.635    1.847
  # 2    cmin  64.557    3.086
  # 3    lapl 434.761   20.785  

  # $`Tiny Sq Matrix`
  #      test elapsed relative
  # 5 pmn.int   0.112    1.000
  # 2    cmin   0.149    1.330
  # 4     pmn   0.174    1.554
  # 1     apl   0.180    1.607
  # 3    lapl   0.509    4.545
$`Square Matrix`
     test elapsed relative
2    cmin   0.216    1.000
1     apl   4.200   19.444
5 pmn.int   4.604   21.315
4     pmn   5.136   23.778
3    lapl  12.546   58.083

$`Tall Matrix`
     test elapsed relative
2    cmin   0.262    1.000
1     apl   3.006   11.473
5 pmn.int  18.605   71.011
3    lapl  22.798   87.015
4     pmn  27.583  105.279

$`Wide-short Matrix`
     test elapsed relative
2    cmin   0.346    1.000
5 pmn.int   3.766   10.884
4     pmn   3.955   11.431
3    lapl  13.393   38.708
1     apl  19.187   55.454

$`Wide-tall Matrix`
     test elapsed relative
2    cmin   5.591    1.000
5 pmn.int  39.466    7.059
4     pmn  40.265    7.202
1     apl  67.151   12.011
3    lapl 158.035   28.266

$`Tiny Sq Matrix`
     test elapsed relative
2    cmin   0.011    1.000
5 pmn.int   0.135   12.273
4     pmn   0.178   16.182
1     apl   0.202   18.364
3    lapl   0.269   24.455