快速计算 R 中 3D 数组一维上的乘积



我有一个三维数组(例如尺寸 = 4000 x 4000 x 2)。现在我想计算第三维的乘积,以获得二维数组(尺寸 = 4000 x 4000)。

我尝试在apply()函数中使用prod()计算乘积;但是这非常耗时。因此,我想知道是否有更快,更有效的计算方法?

apply()方法:

A <- array(runif(4000*4000*2),dim=c(4000,4000,2))
system.time(apply(A, c(1,2), prod))

这里有一个带有数组B的较小示例:

B <- array(c(1,2,1,2,3,4,3,4),dim=c(2,2,2))

结果B_res

B_res <-  array(c(3,3,8,8),dim=c(2,2))

更新:如@42所述-这可以通过元素(手动)乘法来完成,例如:B_res <- B[,,1]*B[,,2]。但是,第三维度的大小范围可能为 2 到 x。因此,手动编码B[,,1]*B[,,2]... *B[,,x]可能不可行。在这里,循环计算可能是一种可能的解决方案:

array_prod <- function(C){
  C_res <- C[,,1]
  for(i in 2:dim(C)[3]){
    C_res <- C_res*C[,,i]
  }
  return(C_res)
}

以下是三种方法(应用、手动元素乘法和循环乘法)的比较:

A <- array(runif(400*400*10),dim=c(400,400,10))
system.time(apply(A, c(1,2), prod)); system.time(A[,,1]*A[,,2]*A[,,3]*A[,,4]*A[,,5]*A[,,6]*A[,,7]*A[,,8]*A[,,9]*A[,,10]); system.time(array_prod(A))
  user  system elapsed 
  0.492   0.021   0.512 
   user  system elapsed 
  0.031   0.000   0.032 
   user  system elapsed 
  0.032   0.001   0.032 

。这表明 Apply 函数明显比其他两种方法慢得多,这两种方法基本上速度相似。

这表明元素

数组乘法是使用 R 中称为矢量化的方法完成的,方法是将前两个维度留空并使用 * 运算符。还可以将 TRUE 表示特定维度的所有实例:

A <- array( 1:(4*4*2),dim=c(4,4,2))
apply(A, c(1,2), prod)
#============
     [,1] [,2] [,3] [,4]
[1,]   17  105  225  377
[2,]   36  132  260  420
[3,]   57  161  297  465
[4,]   80  192  336  512
#=============
A[ , , 1]*A[ , , 2]
     [,1] [,2] [,3] [,4]
[1,]   17  105  225  377
[2,]   36  132  260  420
[3,]   57  161  297  465
[4,]   80  192  336  512

这表明性能提高了 100 倍(尽管我厌倦了等待 4000x4000 版本的 apply 运行,所以我只在该示例中使用矢量化方法显示结果:)

> A <- array(runif(400*400*2),dim=c(400,400,2))
> system.time(apply(A, c(1,2), prod)); system.time(A[,,1]*A[,,2])
   user  system elapsed 
  0.448   0.018   0.452   # the apply timings
   user  system elapsed 
  0.005   0.000   0.004   # the vectorised operation
> A <- array(runif(4000*4000*2),dim=c(4000,4000,2))
>  system.time(A[,,1]*A[,,2])
   user  system elapsed 
  0.525   0.096   0.604 

最新更新