【问题标题】:Faster matrix multiplication by replacing a double loop通过替换双循环更快的矩阵乘法
【发布时间】:2019-10-30 10:48:37
【问题描述】:

我有一个看起来有点像以下代码生成的数据框(但要大得多)

set.seed(10)    
mat <- matrix(rbinom(200, size=1, prob = .5), ncol = 10)

列中有问题,1 表示观察对特定问题感兴趣。我想生成一个网络来比较所有观察结果并计算每个 dyad 共同感兴趣的问题。

我已经生成了以下代码,似乎工作正常:

mat2 <- matrix(NA,20,20)

for(i in 1:nrow(mat)){
    for(j in 1:nrow(mat)){
       mat2[i,j] <- sum(as.numeric(mat[i,]==1) + as.numeric(mat[j,]==1) == 2)
    }
 }

因此,我将每个条目与其他每个条目进行比较,并且只有当两者都有 1 个条目(即他们感兴趣)时,这总和为 2,并且将被视为对某个主题的共同兴趣。

我的问题是我的数据集非常大,现在循环已经运行了几个小时。

有没有人知道如何在避免循环的同时做到这一点?

【问题讨论】:

  • 试试mat %*% t(mat)
  • @Flow 请参阅复制嵌套循环的问题。 stackoverflow.com/questions/58578466/…
  • @Tom 在这种情况下应该是tcrossprod(mat==1)。它非常快。请将其发布为答案!
  • 感谢大家的cmets和答案,非常有帮助!我什至没有考虑过矩阵乘法,尽管这些解决方案非常简单和好。感谢您再次在这里提供帮助。

标签: r loops matrix-multiplication


【解决方案1】:

这应该更快:

tmat <- t(mat==1)
mat4 <- apply(tmat, 2, function(x) colSums(tmat & x))

【讨论】:

    【解决方案2】:

    继续推广@jogo 的评论,因为它是迄今为止最快的(感谢您的提示,我也会在生产中使用它)。

    set.seed(10)    
    mat <- matrix(rbinom(200, size=1, prob = .5), ncol = 10)
    mat2 <- matrix(NA,20,20)
    binary_mat <- mat == 1
    tmat <- t(mat==1)
    
    microbenchmark::microbenchmark(
      "loop" = for(i in 1:nrow(mat)){
                 for(j in 1:nrow(mat)){
                   mat2[i,j] <- sum(as.numeric(mat[i,]==1) + as.numeric(mat[j,]==1) == 2)
                 }
               }, 
      "apply" = mat4 <- apply(tmat, 2, function(x) colSums(tmat & x)), 
      "matrix multiplication" = mat5 <- mat %*% t(mat),
      "tcrossprod" = tcrossprod(mat),
      "tcrossprod binary" = tcrossprod(binary_mat)
    )
    

    在我的机器上,这个基准测试结果

    Unit: microseconds
                      expr       min        lq        mean    median         uq       max neval cld
                      loop 16699.634 16972.271 17931.82535 17180.397 17546.1545 31502.706   100   b
                     apply   322.942   330.046   395.69045   357.886   368.8300  4299.228   100  a 
     matrix multiplication    21.889    28.801    36.76869    39.360    43.9685    50.689   100  a 
                tcrossprod     7.297     8.449    11.20218     9.984    14.4005    18.433   100  a 
         tcrossprod binary     7.680     8.833    11.08316     9.601    12.0970    35.713   100  a 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-25
      • 1970-01-01
      • 1970-01-01
      • 2011-05-31
      • 1970-01-01
      相关资源
      最近更新 更多