如何更改 R 中“foreach”循环中的“for 循环”以快速完成?

问题描述 投票:0回答:1

我想从“for循环”更改为“foreach”以快速完成。从空间数据中,我们可以获得X和Y坐标。以纽约为例,大约有 15,000 个街区组。因此,距离矩阵(mat)可以是 15,000*15,000 个单元格。我不太清楚原因,但获得距离矩阵(A)不需要太多时间。问题是for循环。我需要指示最近 100 个块组(邻居)的权重矩阵 (W)。以下代码可以工作,但速度太慢。我想使用“foreach”和“parallel”库更有效地更改它们。你能让我知道如何更改以下 for 循环吗?非常感谢。

```
coor<-cbind(UA$X, UA$Y) # X, Y coordination
A<-dist(coor, diag=T, upper=T) #distance b/w coor
mat <- as.matrix(A)
q<-100 # it can be changed
W<-array(0L, dim(A)) 

for (i in 1:nrow(mat)){
    W[order(mat[,i])[1:q],i]<-mat[order(mat[,i])[1:q],i]
    D<-apply(W, 2, max, na.rm=TRUE)[i]
    W[order(mat[,i])[1:q],i]<-(1-(W[order(mat[,i])[1:q],i]/D)^3)^3 #tri-cube function
}
```

类似...

```
coor<-cbind(UA$X, UA$Y) # X, Y coordination
A<-dist(coor, diag=T, upper=T) #distance b/w coor
mat <- as.matrix(A)
q<-100 # it can be changed
W<-array(0L, dim(A)) 

foreach::foreach(i = 1:nrow(mat)) %dopar% {
   W[order(mat[,i])[1:q],i]<-mat[order(mat[,i])[1:q],i]
   D<-apply(W, 2, max, na.rm=TRUE)[i]
   W[order(mat[,i])[1:q],i]<-(1-(W[order(mat[,i])[1:q],i]/D)^3)^3 #tri-cube function
}
```
r performance foreach parallel-processing
1个回答
0
投票

这不太适合并行化。来回传递数据需要太多的开销。最近邻算法和稀疏矩阵就是为解决此类问题而设计的。

set.seed(588345973)
x <- runif(15e3)
y <- runif(15e3)
q <- 100L

library(RANN)
library(Matrix)

system.time(
  W <- with(
    nn2(cbind(x, y), k = q),
    sparseMatrix(
      i = nn.idx,
      j = rep.int(1:length(x), q),
      x = c((1 - (nn.dists/nn.dists[,q])^3)^3)
    )
  )
)
#>    user  system elapsed 
#>    0.42    0.02    0.44

与原始方法的优化版本相比:

library(Rfast) # for `Dist`

system.time({
  mat <- Dist(cbind(x, y))
  W2 <- array(0, dim(mat))
  
  for (i in 1:nrow(mat)) {
    o <- order(mat[,i])[1:q]
    W2[o,i] <- (1 - (mat[o,i]/mat[o[q],i])^3)^3
  }
})
#>    user  system elapsed 
#>   13.07    1.11   14.19

检查结果是否相等:

all(sapply(1:length(x), \(i) all.equal(W[,i], W2[,i])))
#> [1] TRUE
© www.soinside.com 2019 - 2024. All rights reserved.