2017-02-10 80 views
2

的我正在翻译在Python至R一些代码涉及3D矩阵。这是非常棘手的,因为我知道很少的Python或矩阵代数。总之在Python代码中,我有一个矩阵dot.product如下:np.dot(A, B)。矩阵A有尺寸(10,4),B是(2,4,2)。 (这些尺寸可能会有所不同,但始终会在第二维上匹配)。所以np.dot与此没有问题作为从文档:- [R等效Python的np.dot为3D阵列

“对于2-d阵列它相当于矩阵乘法,以及用于1-d 阵列矢量的内积(无复共轭)对于 N维它结束的最后一个轴和一个和积的 第二到最后一个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

+1

'B'是一个二维数组,对于一个三维数组,你需要函数'array()'。你也使用'%%'而不是'%*%'。 – LyzandeR

+0

感谢是我应该用'阵列()'和'%*%'。有错别字!现在解决。无论如何 - 修复后的结果是一样的 – user2498193

回答

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) 
+0

非常感谢你这正是我正在寻找。不知道'张量'包,我将不得不熟悉自己! – user2498193

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 

现在具有的填充顺序的了解,让我们试图模仿np.dot中的R具有相同的数据,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 

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

+0

谢谢你的回答,但是对我来说没有什么意义,比如'#注意到尺寸的变化。你已经定义了一个(4,2,2)矩阵,但是我的是一个(2,4,2)矩阵,来自另一个函数的结果。 – user2498193

+1

如果您没有访问该函数,那么您可以编写一个小型转换函数,根据需要将阵列输出更改为所需的格式。所有我想要沟通的是,如果你自己创建一个数组,那么维度的顺序需要与numpy不同。如果返回数组的函数以正确的格式返回它,那么我们应该没问题。 –

+0

好的我非常感谢你! – user2498193