我有一个三维数组(例如尺寸 = 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