A is a 4 dimensional array with dim 100*100*100*100. I want to select 10000 sub matrix from A's last two dimensions. B and C are vectors of length 10000. They are selection criteria. B specifies the row number of A, and C specifies the column number.
A <- array(rnorm(100^4), dim=c(100,100,100,100))
B <- sample( nrow(A) , 10000 , repl = TRUE )
C <- sample( ncol(A) , 10000 , repl = TRUE )
D <- array(0, dim=c(10000,100,100))
With for loop:
system.time(
for ( i in 1:10000 ){
D[i,,] <- A[B[i],C[i],,]
})
user system elapsed
10.20 0.14 10.34
with mapply:
sub_array <- function(b,c) return(A[b,c,,])
system.time(D <- mapply(FUN = sub_array, B, C, SIMPLIFY='array'))
user system elapsed
9.77 3.75 29.17
which is even slower. Is there a faster way to do that? Thanks.
The trick is to re-dim
A
into a 3D array so you can use what we would call "normal" indexing.Some sample data:
OP's method:
Suggested solution:
And we check that the results are identical: