首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在矩阵计算中避免重复的for循环

如何在矩阵计算中避免重复的for循环
EN

Stack Overflow用户
提问于 2020-07-04 21:08:11
回答 3查看 114关注 0票数 2

我的函数可以工作,但当我有大型数据集时,它非常慢。

我能做些什么来加快速度呢?我知道我们应该避免使用双for循环,但我不知道为什么。

非常感谢!

代码语言:javascript
复制
    n <- 3
    wr <- c(0.9, 0.6, 0.5)
    mat <- matrix(1:9, nrow=3, byrow=TRUE)
    
    tmp    <- matrix(nrow = n, ncol = n)
    out   <- rep(0, n)
    
    colsum <- apply(mat, 2, sum)
    
    for (i in 1:n) {
      for (j in 1:n) {
        tmp[i, j] <- (mat[i, j]/ colsum[j])*(1-wr[j])
      }
    }
    
    for (i in 1:n) {
      out[i] <- 1-sum(tmp[1:n,i])
    }
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-07-04 21:25:45

使用apply可以在这里加快速度:

代码语言:javascript
复制
colsum <- apply(mat, 2, sum)
1 - rowSums(apply(mat, 1, function(x) (x / colsum)*(1-wr)))

我们可以清楚地看到使用microbenchmark包和使用更大的n之间的区别

代码语言:javascript
复制
n <- 1000
wr <- rep(c(0.9, 0.6, 0.5), length.out=n)
mat <- matrix(1:(n^2), nrow=n, byrow=TRUE)

tmp <- matrix(nrow = n, ncol = n)
out <- rep(0, n)

colsum <- apply(mat, 2, sum)
    
microbenchmark(
  for_loops = {
    for (i in 1:n) {
      for (j in 1:n) {
        tmp[i, j] <- (mat[i, j]/ colsum[j])*(1-wr[j])
      }
    }
    
    for (i in 1:n) {
      out[i] <- 1-sum(tmp[1:n,i])
    }}, 
  apply = {
    out = 1 - rowSums(apply(mat, 1, function(x) (x / colsum)*(1-wr)))
  }, 
  transpose = {
    tmp = t(t(mat) / colsum * (1-wr))
    out = 1 - colSums(tmp)
  }, 
  rowSums = {
    1 - rowSums(t(mat) / colsum * (1-wr))
  }
)

有趣的是,@BellmanEqn的转置方法似乎比使用apply更快,但使用@user20650提出的rowSums而不是第二次转置甚至超过了平均水平。

代码语言:javascript
复制
# Unit: milliseconds
#      expr      min        lq      mean   median        uq      max neval cld
# for_loops 198.6269 211.68075 246.55071 220.3864 239.66485 476.6462   100   c
#     apply  21.7299  23.98720  39.97067  29.9156  33.85995 232.0723   100  b 
# transpose  11.1222  11.66100  23.86154  13.6034  19.52560 271.2242   100 a  
#   rowSums   8.6790   9.32655  14.09392  10.0072  15.18220 171.8077   100 a  
票数 2
EN

Stack Overflow用户

发布于 2020-07-04 21:24:33

试试这个:

代码语言:javascript
复制
n <- 3
wr <- c(0.9, 0.6, 0.5)
mat <- matrix(1:9, nrow=3, byrow=TRUE)

tmp    <- matrix(nrow = n, ncol = n)
out   <- rep(0, n)

colsum <- apply(mat, 2, sum)

for (i in 1:n) {
  for (j in 1:n) {
    tmp[i, j] <- (mat[i, j]/ colsum[j])*(1-wr[j])
  }
}

for (i in 1:n) {
  out[i] <- 1-sum(tmp[1:n,i])
}

# alternatively:
tmp2 = t(t(mat) / colsum * (1-wr))
out2 = 1 - colSums(tmp)
代码语言:javascript
复制
> tmp
            [,1]       [,2]       [,3]
[1,] 0.008333333 0.05333333 0.08333333
[2,] 0.033333333 0.13333333 0.16666667
[3,] 0.058333333 0.21333333 0.25000000
> out
[1] 0.9 0.6 0.5
代码语言:javascript
复制
> tmp2
            [,1]       [,2]       [,3]
[1,] 0.008333333 0.05333333 0.08333333
[2,] 0.033333333 0.13333333 0.16666667
[3,] 0.058333333 0.21333333 0.25000000
> out2
[1] 0.9 0.6 0.5
票数 3
EN

Stack Overflow用户

发布于 2020-07-04 21:38:42

Base R一行:

代码语言:javascript
复制
1-colSums(t(t(prop.table(mat, 2)) * (1 - wr)))

或使用扫描:

代码语言:javascript
复制
1-rowSums(t(sweep(mat, 2, "/", STATS = colSums(mat))) * (1 - wr))

数据:

代码语言:javascript
复制
n <- 3
wr <- c(0.9, 0.6, 0.5)
mat <- matrix(1:9, nrow=3, byrow=TRUE)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62729526

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档