我想从“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
}
```
这不太适合并行化。来回传递数据需要太多的开销。最近邻算法和稀疏矩阵就是为解决此类问题而设计的。
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