理解 R 中向量和矩阵乘法的输出

问题描述 投票:0回答:1

我目前正在学习 R 中的矩阵运算,在将向量与矩阵相乘时遇到了我没有预料到的输出。我的理解是乘法将按元素进行,但输出表明并非如此。我运行的代码如下:

num_matrix <- matrix(1:9, byrow = TRUE, nrow = 3)
new_matrix <- c(1,2,3) * num_matrix
print(new_matrix)

The output I got is:
[,1] [,2] [,3]
[1,]    1    2    3
[2,]    8   10   12
[3,]   21   24   27

这看起来像是向量 c(1,2,3) 已与 num_matrix 的每一列相乘,这与我最初对按行操作的预期相矛盾。有人可以解释为什么乘法的行为是这样的,而不是像我预期的那样按行进行吗?

此外,如果我想将向量与矩阵的每一行相乘,而不是与每一列相乘,如何在 R 中实现这一点?

感谢您的帮助!

r matrix vector multiplication elementwise-operations
1个回答
0
投票

R 中的矩阵是按列优先顺序排列的向量。您可以转置矩阵,使元素沿着以前的行的列回收,然后转回:

(want_matrix <- t(t(num_matrix) * 1:3))
#>      [,1] [,2] [,3]
#> [1,]    1    4    9
#> [2,]    4   10   18
#> [3,]    7   16   27

为了好玩,这里有一些其他方法及其基准。请注意,当输入较小时,将其视为 matrix 乘法将是最快的,但不能很好地扩展 - 转置更加一致。

f1 <- \(m, v) t(t(m) * v)
f2 <- \(m, v) apply(m, 1, \(r) r*v)
f3 <- \(m, v) sweep(m, 1, v, `*`)
f4 <- \(m, v) m %*% diag(v)

bench <- function(n) {
  m <- matrix(rnorm(n*n), ncol=n)
  v <- runif(n)

  microbenchmark::microbenchmark(
    transpose=f1(m,v),
    apply=f2(m,v),
    sweep=f3(m,v),
    `%*%`=f4(m,v)
  )
}

bench(10)
#> Unit: microseconds
#>       expr  min   lq   mean median   uq  max
#>  transpose  5.8  6.1  6.718   6.20  6.5 20.5
#>      apply 26.0 27.4 29.764  28.10 29.8 58.3
#>      sweep 20.7 21.7 24.351  22.85 23.6 99.8
#>        %*%  2.2  2.4  3.176   2.60  2.8 26.2

bench(100)
#> Unit: microseconds
#>       expr   min     lq    mean median     uq     max
#>  transpose  36.0  61.45 165.074  63.35  67.70 10192.8
#>      apply 197.7 241.55 285.582 268.25 309.70   641.0
#>      sweep  57.7  83.65  91.682  88.60  94.25   224.9
#>        %*% 460.5 493.85 504.451 496.95 503.65   829.9
© www.soinside.com 2019 - 2024. All rights reserved.