从矩阵中的每列中提取min的最快方法是什么?
<小时/>
将所有基准移至下面的答案。
## TEST DATA
set.seed(1)
matrix.inputs <- list(
"Square Matrix" = matrix(sample(seq(1e6), 4^2*1e4, T), ncol=400), # 400 x 400
"Tall Matrix" = matrix(sample(seq(1e6), 4^2*1e4, T), nrow=4000), # 4000 x 40
"Wide-short Matrix" = matrix(sample(seq(1e6), 4^2*1e4, T), ncol=4000), # 40 x 4000
"Wide-tall Matrix" = matrix(sample(seq(1e6), 4^2*1e5, T), ncol=4000), # 400 x 4000
"Tiny Sq Matrix" = matrix(sample(seq(1e6), 4^2*1e2, T), ncol=40) # 40 x 40
)
答案 0 :(得分:10)
sos
套餐非常适合回答这些问题。
library("sos")
findFn("colMins")
library("matrixStats")
?colMins
http://finzi.psych.upenn.edu/R/library/matrixStats/html/rowRanges.html
奇怪的是,对于我尝试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
答案 1 :(得分:9)
这是在正方形和宽矩阵上更快的一个。它在矩阵的行上使用pmin
。 (如果您知道将矩阵拆分成行的更快方法,请随时编辑)
do.call(pmin, lapply(1:nrow(mat), function(i)mat[i,]))
使用与@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
答案 2 :(得分:6)
更新2014-12-17 :
colMins()
等。在matrixStats的最新版本中,速度明显加快。这是使用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-09 :
仅供参考,自matrixStats v0.8.7(2013-07-28)以来,colMins()
的速度大约是之前的两倍。原因是此前使用的函数colRanges()
解释了此处报告的“令人惊讶的缓慢”结果。 colMaxs()
,rowMins()
和rowMaxs()
的速度相同。
答案 3 :(得分:3)
lapply( split(mat, rep(1:dim(mat)[1], each=dim(mat)[2])), min)
which( ! apply(my.mat, 2, min, na.rm=T) ==
sapply( split(my.mat, rep(1:dim(my.mat)[1], each=dim(my.mat)[2])), min) )
# named integer(0)
答案 4 :(得分:2)
以下是目前为止的答案集。随着更多答案的提供,这将更新。
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
答案 5 :(得分:1)
mat[(1:ncol(mat)-1)*nrow(mat)+max.col(t(-mat))]
似乎很快,而且它是基础R。