R - 向量化哪个操作
Posted
技术标签:
【中文标题】R - 向量化哪个操作【英文标题】:R - vectorizing a which operation 【发布时间】:2012-06-26 09:31:39 【问题描述】:您好,我在 R 中有一个函数,我正在尝试优化性能。我需要矢量化一个 for 循环。我的问题是稍微复杂的数据结构以及我需要使用“which”命令执行查找的方式。
假设我们正在处理 5 个元素 (1,2,3,4,5),10x2 矩阵对是 5 个元素的所有唯一对的组合(即 (1,2), (1,3) ,(1,4) ....(4,5))。 all_prods 是一个 10x1 矩阵,我需要在遍历所有 5 个元素时使用这些对进行查找。
所以对于 1,我需要从 all_prods 中索引第 1、2、3、4 行(对 1、2、1、3、1、4 和 1,5),依此类推,对于 1、2、3、4、5 .
我最近才从 matlab 切换到 R,因此非常感谢任何帮助。
foo <- function(AA , BB , CC )
pa <- AA*CC;
pairs <- t(combn(seq_len(length(AA)),2));
all_prods <- pa[pairs[,1]] * pa[pairs[,2]];
result <- matrix(0,1,length(AA));
# WANT TO VECTORIZE THIS BLOCK
for(st in seq(from=1,to=length(AA)))
result[st] <- sum(all_prods[c(which(pairs[,1]==st), which(pairs[,2]==st))])*BB[st];
return(result);
AA <- seq(from=1,to=5); BB<-seq(from=11,to=15); CC<-seq(from=21,to=25);
results <- foo(AA,BB,CC);
#final results is [7715 164208 256542 348096 431250]
我想将 for 循环转换为矢量化版本。我不想循环遍历每个元素 st,而是想在一个命令中完成它,该命令给我一个结果向量(而不是逐个元素地构建它)
【问题讨论】:
我建议你提供一些示例数据来玩。见***.com/questions/5963269/… 我不确定这是你的瓶颈。您预先分配了一个很好的矩阵,但combn
和 t
非常贪婪。您是否尝试过分析您的代码?
我想将 for 循环转换为矢量化版本。我不想循环遍历每个元素 st,而是想在一个命令中完成它,该命令给我一个结果向量(而不是一个一个地构建它)。我很抱歉没有让这个更清楚。我已经更新了帖子。
我尝试了sapply
解决方案,但它与您所取得的成就相当(感谢预先分配您的对象)。在分析之后,似乎大部分时间都花在了which
。 Rprof("vekt.txt"); results <- foo(AA,BB,CC); Rprof(); summaryRprof("vekt.txt")
再次感谢罗曼。这就是为什么我想将它矢量化或以另一种方式重写它(我的理解是 apply 系列是编写循环的一种优雅方式,但不是性能改进)。还要进一步感谢您向我介绍 RProf :)
【参考方案1】:
你可以这样写你的函数:
foo <- function(AA, BB, CC)
pa <- AA*CC
x <- outer(pa, pa)
diag(x) <- 0
res <- colSums(x)*BB
return(res)
关键思想是不打破对称性。您对有序pairs
的使用对应于我的矩阵x
的右上三角形。尽管这看起来只是要计算的值的一半,但语法和计算开销变得相当大。您正在区分 st
是该对中的第一个元素和第二个元素的情况。稍后这会导致摆脱这种区别相当麻烦。有了完整的对称矩阵,您就不必担心顺序,并且事情会顺利矢量化。
【讨论】:
以上是关于R - 向量化哪个操作的主要内容,如果未能解决你的问题,请参考以下文章