【问题标题】:R equivalent of Python's np.dot for 3D arrayR 等效于 Python 的 np.dot 用于 3D 数组
【发布时间】:2017-02-10 11:23:41
【问题描述】:

我正在将一些涉及 3D 矩阵的代码从 Python 翻译成 R。这很棘手,因为我对 Python 或矩阵代数知之甚少。无论如何,在 Python 代码中,我有一个矩阵 dot.product 如下:np.dot(A, B)。矩阵 A 的维数为 (10, 4),B 的维数为 (2, 4, 2)。 (这些维度可能会有所不同,但总是会在第二个维度上匹配)。所以 np.dot 从文档中对此没有任何问题:

"对于二维数组,它等价于矩阵乘法,对于一维数组 数组到向量的内积(没有复共轭)。为了 N维它是a的最后一个轴上的和积 b 的倒数第二个:"

因此它沿 A=4 的第二个轴和 B=4 的中轴相乘,并输出一个 (10,2,2) 矩阵。 => 没问题。但是在 R 中,%*% 没有这种行为并会引发“不符合数组”的错误。

r 中的玩具示例:

A <- matrix( rnorm(10*4), nrow=10, ncol=4)
B <- array( rnorm(2*4*2), c(2,4,2))
A %*% B
Error in A %*% B : non-conformable arrays

如何解决这个问题以实现与np.dot 相同的计算?

【问题讨论】:

  • B 是一个 2-D 数组,对于 3-D 数组,您需要函数 array()。您还使用了%% 而不是%*%
  • 谢谢,是的,我应该使用array()%*%。有错别字!现在修复。无论如何 - 修复后结果是一样的

标签: python arrays r numpy matrix


【解决方案1】:

我们可以使用aperm()tensor::tensor 来做到这一点。使用@SandipanDey 的示例。

设置数组(你需要aperm来获取合适的B,我这里叫B2):

A <- matrix(0:39,ncol=4,byrow=TRUE)
B <- array(0:15,dim=c(2,4,2))
B2 <- aperm(B,c(2,1,3),resize=TRUE)

tensor::tensor 进行了正确的计算,但我们需要重塑结果:

library(tensor)
C <- tensor(A,B2,2,1)
aperm(C,c(3,2,1),resize=TRUE)

【讨论】:

  • 非常感谢您,这正是我想要的。不知道 tensor 包我必须熟悉自己!
【解决方案2】:

我们先来尝试理解python numpyR中多维数组的填充顺序,它们是不一样的。

python

import numpy as np
np.arange(16).reshape((2,4,2)) # fill with 0:15

#[[[ 0  1]
#  [ 2  3]
#  [ 4  5]
#  [ 6  7]]

# [[ 8  9]
#  [10 11]
#  [12 13]
#  [14 15]]]

R

array(0:15, dim=c(2,4,2)) # fill with 0:15
#, , 1
#      [,1] [,2] [,3] [,4]
#[1,]    0    2    4    6
#[2,]    1    3    5    7
#, , 2
#     [,1] [,2] [,3] [,4]
#[1,]    8   10   12   14
#[2,]    9   11   13   15

现在了解了填充顺序,让我们尝试用相同的数据在 R 中模拟 np.dotA,B 作为输入数组,C 作为输出数组(为此我们需要更改顺序尺寸):

python:

import numpy as np
a = np.arange(40).reshape((10,4))    # 0:39
b = np.arange(16).reshape((2,4,2))   # 0:15

print a
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [12 13 14 15]
 [16 17 18 19]
 [20 21 22 23]
 [24 25 26 27]
 [28 29 30 31]
 [32 33 34 35]
 [36 37 38 39]]

print b
[[[ 0  1]
  [ 2  3]
  [ 4  5]
  [ 6  7]]

 [[ 8  9]
  [10 11]
  [12 13]
  [14 15]]]

print np.dot(a, b)
[[[  28   34]
  [  76   82]]

 [[  76   98]
  [ 252  274]]

 [[ 124  162]
  [ 428  466]]

 [[ 172  226]
  [ 604  658]]

 [[ 220  290]
  [ 780  850]]

 [[ 268  354]
  [ 956 1042]]

 [[ 316  418]
  [1132 1234]]

 [[ 364  482]
  [1308 1426]]

 [[ 412  546]
  [1484 1618]]

 [[ 460  610]
  [1660 1810]]]

R 中要获得相同的结果,我们需要以下代码:

A <- matrix(0:39, nrow=10, byrow=TRUE) # 0:39
A
      [,1] [,2] [,3] [,4]
 [1,]    0    1    2    3
 [2,]    4    5    6    7
 [3,]    8    9   10   11
 [4,]   12   13   14   15
 [5,]   16   17   18   19
 [6,]   20   21   22   23
 [7,]   24   25   26   27
 [8,]   28   29   30   31
 [9,]   32   33   34   35
[10,]   36   37   38   39

B <- array(0, dim=c(4,2,2)) # notice the change in dimensions
B[,,1] <- matrix(0:7, nrow=4, byrow=TRUE)
B[,,2] <- matrix(8:15, nrow=4, byrow=TRUE)
B                                 # 0:15
, , 1

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

, , 2

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

C <- array(0, dim=c(2,2,10)) # again note the change in dimensions
for (i in 1:10) {
  for (j in 1:2) {
    for (k in 1:2) {
      C[k,j,i] = sum(A[i,]*B[,j,k])
    }
  }
}
C
, , 1

     [,1] [,2]
[1,]   28   34
[2,]   76   82

, , 2

     [,1] [,2]
[1,]   76   98
[2,]  252  274

, , 3

     [,1] [,2]
[1,]  124  162
[2,]  428  466

, , 4

     [,1] [,2]
[1,]  172  226
[2,]  604  658

, , 5

     [,1] [,2]
[1,]  220  290
[2,]  780  850

, , 6

     [,1] [,2]
[1,]  268  354
[2,]  956 1042

, , 7

     [,1] [,2]
[1,]  316  418
[2,] 1132 1234

, , 8

     [,1] [,2]
[1,]  364  482
[2,] 1308 1426

, , 9

     [,1] [,2]
[1,]  412  546
[2,] 1484 1618

, , 10

     [,1] [,2]
[1,]  460  610
[2,] 1660 1810  

我们可以看到结果是完全一样的。现在您可以尝试使用自己的数据。

【讨论】:

  • 感谢您的回答,但有些东西对我来说没有意义 - 即# notice the change in dimensions。您已经定义了一个 (4, 2, 2) 矩阵,但我的是一个 (2, 4, 2) 矩阵,它是来自另一个函数的结果。
  • 如果您无权访问该函数,那么您可以编写一个小的转换函数,如果需要,将数组输出更改为所需的格式。我想要传达的是,如果您自己创建一个数组,维度的顺序需要与 numpy 不同。如果返回数组的函数以正确的格式返回它,那么我们应该没问题。
猜你喜欢
  • 2017-03-07
  • 1970-01-01
  • 2020-03-18
  • 2015-12-28
  • 2015-08-04
  • 2022-03-03
  • 2021-12-29
  • 2013-04-26
  • 2023-03-24
相关资源
最近更新 更多