gpt4 book ai didi

r - R中执行两个嵌套for循环的快速方法

转载 作者:行者123 更新时间:2023-12-03 16:13:47 26 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





Subtract every element of vector A from every element of vector B

(4 个回答)


4年前关闭。




我需要取两个向量的任意两个元素之间的差异。
A<-c(1,2)B<-c(3,4)那么我的结果 R应该是 c(3-1,3-2,4-1,4-2) .

有了这个片段

myfunction <- function(N)
{
A = runif(N)
B = runif(N)
R = c()
for(a in A){
for(b in B){
R=c(b-a,R)
}
}
R
}
print(system.time(result <- myfunction(300)))

这次我明白了
   user  system elapsed 
14.27 0.01 14.39

有没有更快的方法来做到这一点?

最佳答案

最快的基本解决方案是使用 outer :

as.vector(outer(B,A,"-"))

令我惊讶的是, map2_dbl实际上比 outer快很多:

不出我所料, map2_dbl看起来更快,但那是因为它没有计算 A 和 B 中值的每个组合:
      test elapsed relative
3 CP(A, B) 7.54 47.125 # using expand.grid
2 JL(A, B) 0.16 1.000 # using map2_dbl
1 JM(A, B) 3.13 19.563 # using outer

但:
> A <- 1:3
> B <- 3:1
> JL(A,B)
[1] -2 0 2
> JM(A,B)
[1] 2 1 0 1 0 -1 0 -1 -2

这是针对两个长度为 1000 且重复 100 次的向量。我没有包含您自己的解决方案,因为该解决方案速度慢得可笑,原因有两个:
  • for R 中的循环比过去快了很多,但仍然不如使用循环编码在 C 中的函数那么理想。或等效的。此处测试代码中使用的函数就是这种情况。
  • 你“增长”你的结果对象。每次循环代码,即 R变得更大一个值,因此 R 必须在内存中寻找一个新位置来存储它。这实际上是您代码中最大的瓶颈。尝试不惜一切代价避免这种构造,因为它是导致代码极其缓慢的最重要原因之一。

  • 基准代码:
    library(tidyverse)

    JM <- function(A,B){
    as.vector(outer(B,A,"-"))
    }

    JL <- function(A,B){
    map2_dbl(.x = A,
    .y = B,
    .f = ~ c(.x - .y))
    }

    CP <- function(A,B){
    as.data.frame(expand.grid(A,B)) %>%
    mutate(Var3 = Var2-Var1)
    }

    library(rbenchmark)

    A <- runif(1000)
    B <- runif(1000)

    benchmark(JM(A,B),
    JL(A,B),
    CP(A,B),
    replications = 100,
    columns = c("test","elapsed","relative"))

    关于r - R中执行两个嵌套for循环的快速方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45077747/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com