r - 如何为嵌套矩阵匹配和 colSums 加速 R 中的 for 循环
问题描述
我有一个明显简单的问题,我需要比我开发的更快的 R 实现
我为此示例初始化随机种子和维度:
set.seed(1)
d1<-400
d2<-20000
d3<-50
我有一个矩阵 X,尺寸为d1 x d2:
X<-as.data.frame(matrix(rnorm(d1*d2),nrow=d1,ncol=d2))
rownames(X)<-paste0("row",1:nrow(X))
colnames(X)<-paste0("col",1:ncol(X))
以及具有d1行索引的向量 u:
u<-sample(rownames(X),nrow(X),replace=TRUE)
我还有一个矩阵 C 与命名行和维度d3 x d2:
C<-matrix(rnorm(d3*d2),nrow=d3,ncol=d2)
rownames(C)<-sample(rownames(X),nrow(C),replace=FALSE)
现在,通过以下非常慢的循环,我用匹配的 X 行的总和填充矩阵 C:
system.time(
for(i in 1:nrow(C)){
indexes<-which(u==rownames(C)[i])
C[i,] <- colSums(X[indexes,])
}
)
此操作在我的 PC 上大约需要 11.5 秒,但我确信可以通过避免 for 循环来加快速度。有任何想法吗?非常感谢!
解决方案
您可以尝试使用sapply
for 循环。
system.time(
C2 <- `dimnames<-`(t(sapply(match(rownames(C), u), function(x)
colSums(X[x, ]))), list(rownames(C), NULL))
)
# user system elapsed
# 20.06 0.03 20.14
stopifnot(all.equal(C, C2))
相比
system.time(
for(i in 1:nrow(C)){
indexes <- which(u == rownames(C)[i])
C[i, ] <- colSums(X[indexes, ])
}
)
# user system elapsed
# 20.76 0.69 28.30
然而,目前它只是一个单一的测量值。
更新
好像跑的快了点……
Unit: seconds
expr min lq mean median uq max neval cld
forloop 20.44852 20.57730 21.67771 20.74106 21.01723 29.63220 10 a
sapply 19.86707 20.17126 21.34529 20.50283 20.81254 29.73764 10 a
更新 2
但是你可以用parallel::parSapply
.
system.time({
library(parallel)
cl <- makeCluster(detectCores() - 1)
clusterExport(cl, c("C", "u", "X"))
C3 <- parSapply(cl, match(rownames(C), u), function(x) colSums(X[x, ]))
stopCluster(cl)
C3 <- `dimnames<-`(t(C3), list(rownames(C), NULL))
})
# user system elapsed
# 0.81 3.16 9.82
stopifnot(all.equal(C, C3))
现在,我的机器和你的机器一样快,有了for
-loop :)
推荐阅读
- php - 如何从 PHP 中的 .docx 文件中删除邮件合并字段?
- amazon-web-services - AWS cloudwatch 中的 web-1.log 与 web.stdout.log
- reactjs - 如何清除焦点上的数字输入字段
- sql-server - EFCore Scaffold-DbContext SqlClient.SqlException (0x80131904):列名无效
- python - 使用编码/数据库 fecthall 方法的值替换
- python - 从维基百科获取和解析数据
- mysql - MySQL:添加外键约束失败
- wordpress - 如何将 Wordpress 类别转换为自定义帖子类型?
- hotchocolate - 使用 Hot Chocolate 时,有没有办法实现按请求事务处理的中间件?
- python - 我无法从 URL 中获取文本 (BeautifullSoup)