减去R中具有不同大小的数组

时间:2019-06-19 11:37:54

标签: arrays r

AB分别是维度为[3,4,5][4,5]的数组。

例如

A <- array(100,c(3, 4,5))
B <- array(80,    c(4,5))

我想要的答案是一个维度为C的数组[3,4,5],使得

C[i,j,k] = A[i,j,k] - B[j,k]

对于所有i,j,k


编辑 哪个答案是最快的代码?

要评估以下三个答案,我执行了以下代码以量化这三个代码的时间。 结果如下:

> mb
Unit: microseconds
 expr  min    lq   mean median    uq   max neval
   f1 28.4 33.00 37.329  34.75 37.00 213.5   100
   f2 32.5 37.65 40.069  38.95 40.55 103.0   100
   f3 33.8 40.25 42.397  41.65 43.30  64.5   100

因此f1最快,因此我选择@user10488504的答案作为该问题的答案。 谢谢三个人@user10488504@Stéphane Laurent@Lyngbakr。我将在您的包装中使用您的建议代码。它对我有很大帮助。 enter image description here 代码,用于计算运行时间。

f1 <- function(){
A <- array(1:100, c(3, 4, 5))
B <- array(1:80, c(4,5))

C <- array(aperm(sapply(1:dim(A)[1], function(i) A[i,,] - B)), dim(A))

}


f2<-function(){

A <- array(1:100, c(3, 4, 5))
B <- array(1:80, c(4,5))
sweep(A, c(2,3), B)
}

f3 <- function(){

A <- array(1:100, c(3, 4, 5))
B <- array(1:80, c(4,5))

# Perform calculation
res <- array(t(apply(A, MARGIN = 1, function(x)x-B)), c(3, 4, 5))
}


library(microbenchmark)
library(ggplot2)

mb <- microbenchmark(
  f1 = f1(),
  f2 = f2(),
  f3 = f3()
)

mb
autoplot(mb)

3 个答案:

答案 0 :(得分:5)

使用sweep

A <- array(1:100, c(3, 4, 5))
B <- array(1:80, c(4,5))
> sweep(A, c(2,3), B)
, , 1

     [,1] [,2] [,3] [,4]
[1,]    0    2    4    6
[2,]    1    3    5    7
[3,]    2    4    6    8

, , 2

     [,1] [,2] [,3] [,4]
[1,]    8   10   12   14
[2,]    9   11   13   15
[3,]   10   12   14   16

, , 3

     [,1] [,2] [,3] [,4]
[1,]   16   18   20   22
[2,]   17   19   21   23
[3,]   18   20   22   24

, , 4

     [,1] [,2] [,3] [,4]
[1,]   24   26   28   30
[2,]   25   27   29   31
[3,]   26   28   30   32

, , 5

     [,1] [,2] [,3] [,4]
[1,]   32   34   36   38
[2,]   33   35   37   39
[3,]   34   36   38   40

答案 1 :(得分:4)

您可以使用sapplyaperm来做到这一点,例如:

C <- array(aperm(sapply(1:dim(A)[1], function(i) A[i,,] - B)), dim(A))

答案 2 :(得分:1)

这里是使用apply的尝试。

# Define arrays
A <- array(1:100, c(3, 4, 5))
B <- array(1:80, c(4,5))

# Perform calculation
res <- array(t(apply(A, MARGIN = 1, function(x)x-B)), c(3, 4, 5))

# Check result
res[1,,]
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,]    0    8   16   24   32
#> [2,]    2   10   18   26   34
#> [3,]    4   12   20   28   36
#> [4,]    6   14   22   30   38
A[1,,] - B
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,]    0    8   16   24   32
#> [2,]    2   10   18   26   34
#> [3,]    4   12   20   28   36
#> [4,]    6   14   22   30   38

reprex package(v0.3.0)于2019-06-19创建