【问题标题】:R - How can I make this loop faster?R - 我怎样才能使这个循环更快?
【发布时间】:2020-02-20 14:20:53
【问题描述】:

有没有办法让这个循环在 r 中更快?

    V=array(NA, dim=c(nrow(pixDF), n))

    for(i in 1:n)
    {
       sdC<-sqrt(det(Cov[,i,]))
       iC<-inv(Cov[,i,])
       V[,i]<-apply(pixDF,1,function(x)(sdC*exp(-0.5*((x-Mean[i,])%*%iC%*%as.matrix((x-Mean[i,]))))))
    }

在这种情况下,pixDF 是一个包含 490000 行和 4 列的矩阵,其中填充了双精度数。 n = 5。Cov 是一个 (4,5,4) 数组,其中填充了“双精度”。 Mean 是一个 (5,4) 数组,也填充了双精度数。

这个循环在我的电脑上大约需要 30 分钟。 (编辑前)。 现在需要 1 分钟。

【问题讨论】:

  • 为什么pixDF 不是矩阵?你在apply 循环中做了很多事情,这些事情只需要在周围的for 循环中计算一次,例如,sqrt(det(Cov[,i,])) 不需要为pixDF 的每一行单独计算。跨度>
  • 如果您将可重现的示例与预期输出一起包含在内,会更容易提供帮助。请阅读有关how to ask a good question 的信息以及如何提供reproducible example。
  • @Roland 我不知道矩阵的内存效率更高。在 apply 之外计算 sqrt(det(Cov[,i,])) 并使用矩阵而不是 data.frame 后并没有太大变化,但在计算 inv(Cov[, i ,]) 之前使其更快(60秒)。非常感谢。
  • 我不知道 inv 函数,但如果它确实如其名称所述,让我指出对数字的一般建议:避免反转矩阵。这是昂贵的,并且会产生(损失)精度的问题。通常情况下,最好solve方程系统。

标签: r performance loops


【解决方案1】:

正如 Ronak 所说,如果没有可重复的示例,就很难提供帮助。但是,我认为apply 是可以避免的。像这样的东西可以工作:

V <- array(NA, dim = c(nrow(pixDF), n))
tpixDF <- t(pixDF)
for (i in 1:n) {
  x <- Cov[, i, ]
  sdC <- sqrt(det(x))
  iC <- solve(x)
  mi <- Mean[i, ]
  k <- t(tpixDF - mi)
  V[, i] <- sdC*exp(-0.5*rowSums(k %*% iC * k))
}

另外,正如 Roland 提到的,inv 可能等于 solve。

【讨论】:

  • 非常感谢,现在速度更快了。对不起,我是新来的,下次我会尝试给出一个可重现的例子。但是为什么solve 比inv 更好(或更精确)?而且,由于您的示例有效,* 发生在 %*% 之前,对吧?
  • @PedroM。您使用的是哪些软件包inv,您没有提到吗?例如pracma::inv 在其代码中使用solve。 %*% 首先发生。尝试运行k %*% (iC * k)...
  • @PedroM。 solve 如果您实际使用它来求解矩阵方程而不是反转矩阵,则更好,即使用solve(X, y) 而不是solve(X) %*% y。
猜你喜欢
  • 2017-12-20
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-04
  • 2020-08-14
  • 2021-02-17
  • 1970-01-01
相关资源
最近更新 更多