高效地复制R中的矩阵 [英] Efficiently replicate matrices in R

查看:29
本文介绍了高效地复制R中的矩阵的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个矩阵,并寻找一种有效的方法将其复制n次(其中n是数据集中的观测值)。例如,如果我有一个矩阵A

A <- 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))版本稍微快一些,但比applymatrix版本慢不了多少。因此,在这种情况下,对任意n的泛化不需要降低速度。

这篇关于高效地复制R中的矩阵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆