我正在将一些代码从Python翻译成涉及3D矩阵的R.这很棘手,因为我对Python或矩阵代数知之甚少。无论如何在Python代码中我有一个矩阵dot.product如下:np.dot(A, B)
。矩阵A具有尺寸(10,4),B是(2,4,2)。 (这些尺寸可能会有所不同,但总是会在第二个尺寸上匹配)。所以np.dot对文档没有任何问题:
"对于2-D阵列,它相当于矩阵乘法,对于1-D 阵列到载体的内积(没有复共轭)。对于 N维是a和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
相同的计算?
答案 0 :(得分:4)
我们可以使用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)
答案 1 :(得分:3)
让我们首先尝试理解在python numpy
和R
中填充多维数组的顺序,它们是不同的。
在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.dot
,A,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
我们可以看到结果完全相同。现在,您可以尝试使用自己的数据。