本文介绍了高效地复制R中的矩阵的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有一个矩阵,并寻找一种有效的方法将其复制n次(其中n是数据集中的观测值)。例如,如果我有一个矩阵AA <- matrix(1:15, nrow=3)
然后我想要表单的输出
rbind(A, A, A, ...) #n times
。
for
循环或apply
或类似的函数。然而,对"矩阵复制函数"的调用发生在我的优化算法的核心,在我的程序的一次运行中,它被调用了数万次。因此,循环、应用类型的函数和任何类似的函数都不够高效。(这样的解决方案基本上意味着在n上循环执行数万次,这显然是低效的。)我已经尝试使用普通的rep
函数,但还没有找到将rep
的输出排列成所需格式的矩阵的方法。解决方案do.call("rbind", replicate(n, A, simplify=F))
效率也太低,因为在这种情况下使用rbind
太频繁了。(然后,我的程序大约30%的总运行时间用于执行rbind。)
有人知道更好的解决方案吗?
推荐答案
另外两个解决方案:
第一个是对问题中的示例的修改
do.call("rbind", rep(list(A), n))
第二步涉及展开矩阵、复制矩阵和重新组装矩阵。
matrix(rep(t(A),n), ncol=ncol(A), byrow=TRUE)
因为效率是所要求的,所以基准是必要的
library("rbenchmark")
A <- matrix(1:15, nrow=3)
n <- 10
benchmark(rbind(A, A, A, A, A, A, A, A, A, A),
do.call("rbind", replicate(n, A, simplify=FALSE)),
do.call("rbind", rep(list(A), n)),
apply(A, 2, rep, n),
matrix(rep(t(A),n), ncol=ncol(A), byrow=TRUE),
order="relative", replications=100000)
这提供了:
test replications elapsed
1 rbind(A, A, A, A, A, A, A, A, A, A) 100000 0.91
3 do.call("rbind", rep(list(A), n)) 100000 1.42
5 matrix(rep(t(A), n), ncol = ncol(A), byrow = TRUE) 100000 2.20
2 do.call("rbind", replicate(n, A, simplify = FALSE)) 100000 3.03
4 apply(A, 2, rep, n) 100000 7.75
relative user.self sys.self user.child sys.child
1 1.000 0.91 0 NA NA
3 1.560 1.42 0 NA NA
5 2.418 2.19 0 NA NA
2 3.330 3.03 0 NA NA
4 8.516 7.73 0 NA NA
所以最快的是原始rbind
调用,但前提是n
是固定的并且提前知道。如果n
不固定,则最快的是do.call("rbind", rep(list(A), n)
。这是一个3x5矩阵和10个副本。大小不同的矩阵可能会给出不同的排序。
编辑:
对于n=600,结果的顺序不同(省略显式rbind
版本):
A <- matrix(1:15, nrow=3)
n <- 600
benchmark(do.call("rbind", replicate(n, A, simplify=FALSE)),
do.call("rbind", rep(list(A), n)),
apply(A, 2, rep, n),
matrix(rep(t(A),n), ncol=ncol(A), byrow=TRUE),
order="relative", replications=10000)
赠送
test replications elapsed
4 matrix(rep(t(A), n), ncol = ncol(A), byrow = TRUE) 10000 1.74
3 apply(A, 2, rep, n) 10000 2.57
2 do.call("rbind", rep(list(A), n)) 10000 2.79
1 do.call("rbind", replicate(n, A, simplify = FALSE)) 10000 6.68
relative user.self sys.self user.child sys.child
4 1.000 1.75 0 NA NA
3 1.477 2.54 0 NA NA
2 1.603 2.79 0 NA NA
1 3.839 6.65 0 NA NA
如果包含显式rbind
版本,则它比do.call("rbind", rep(list(A), n))
版本稍微快一些,但比apply
或matrix
版本慢不了多少。因此,在这种情况下,对任意n
的泛化不需要降低速度。 这篇关于高效地复制R中的矩阵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!