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/… 我不确定这是你的瓶颈。您预先分配了一个很好的矩阵,但 combnt 非常贪婪。您是否尝试过分析您的代码? 我想将 for 循环转换为矢量化版本。我不想循环遍历每个元素 st,而是想在一个命令中完成它,该命令给我一个结果向量(而不是一个一个地构建它)。我很抱歉没有让这个更清楚。我已经更新了帖子。 我尝试了sapply 解决方案,但它与您所取得的成就相当(感谢预先分配您的对象)。在分析之后,似乎大部分时间都花在了whichRprof("vekt.txt"); results &lt;- 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 - 向量化哪个操作的主要内容,如果未能解决你的问题,请参考以下文章

R中真正快速的词ngram向量化

R语言进阶之4:数据整形(reshape)

如何构建词空间向量和文本向量化

如何确定向量长度以确保向量化过程中没有向量依赖性?

R语言 | 向量化操作purrr包

r data.table中的向量化表操作