将2D数组乘以另一个2D数组中正确索引的缩放器

时间:2019-03-30 05:30:56

标签: python numpy

尝试乘以

的数组时
v = [ ['x1','y1','z1'], ['x2','y2','z2'] ]

通过缩放器数组的正确索引

 b = [ ['t1','c1'], ['t2','c2'] ] 

我希望得到输出:

```
[
[ [x1 * t1, y1 * t1, z1 * t1], [x2 * c1, y2 * c1, z2 * c1] ],
[ [x1 * t2, y1 * t2, z1 * t2], [x2 * c2, y2 * c2, z2 * c2] ]
]
```

我可以通过执行以下循环来实现:

out = []
for i in b:
   for h in range(len(v):
       out.append(v[h] * i[h])

我该如何在numpy中正确乘以矩阵?

2 个答案:

答案 0 :(得分:1)

您想要的是外部产品。

只是为了好玩,我会坚持使用您的字符串,但是创建object dtype数组:

In [677]: v = np.array([ ['x1','y1','z1'], ['x2','y2','z2'] ],object)           
In [678]: v                                                                     
Out[678]: 
array([['x1', 'y1', 'z1'],
       ['x2', 'y2', 'z2']], dtype=object)
In [679]: b = np.array([ ['t1','c1'], ['t2','c2'] ] ,object)                    
In [680]: v.shape                                                               
Out[680]: (2, 3)
In [681]: b.shape                                                               
Out[681]: (2, 2)

然后,如果我使用broadcastingplus(对于字符串来说是join),我得到:

In [683]: v[None,:,:]+b[:,:,None]                                               
Out[683]: 
array([[['x1t1', 'y1t1', 'z1t1'],
        ['x2c1', 'y2c1', 'z2c1']],

       [['x1t2', 'y1t2', 'z1t2'],
        ['x2c2', 'y2c2', 'z2c2']]], dtype=object)

通过将(2,3)数组与(2,2)相乘,将它们扩展为(1,2,3)和(2,2,1)=>(2,2,3)

同一件事,但带有数字数组,允许我使用+或*:

In [684]: V = np.arange(10,70,10).reshape(2,3)                                  
In [685]: B = np.arange(1,5).reshape(2,2)                                       
In [686]: V[None,:,:]+B[:,:,None]                                               
Out[686]: 
array([[[11, 21, 31],
        [42, 52, 62]],

       [[13, 23, 33],
        [44, 54, 64]]])
In [687]: V[None,:,:]*B[:,:,None]                                               
Out[687]: 
array([[[ 10,  20,  30],
        [ 80, 100, 120]],

       [[ 30,  60,  90],
        [160, 200, 240]]])

您的循环代码不完全相同(相同的组合,但形​​状不同)

In [697]: out = [] 
     ...: for i in b: 
     ...:     for h in range(2): 
     ...:         out.append(v[h] + i[h]) 
     ...: np.array(out)                                                         
Out[697]: 
array([['x1t1', 'y1t1', 'z1t1'],
       ['x2c1', 'y2c1', 'z2c1'],
       ['x1t2', 'y1t2', 'z1t2'],
       ['x2c2', 'y2c2', 'z2c2']], dtype=object)

In [699]: out = [] 
     ...: for i in B: 
     ...:     for h in range(2): 
     ...:         out.append(V[h] * i[h]) 
     ...: np.array(out)                                                         
Out[699]: 
array([[ 10,  20,  30],
       [ 80, 100, 120],
       [ 30,  60,  90],
       [160, 200, 240]])

einsum是表达这些组合的另一种方式:

In [708]: np.einsum('ij,jk->ijk',B,V)                                           
Out[708]: 
array([[[ 10,  20,  30],
        [ 80, 100, 120]],

       [[ 30,  60,  90],
        [160, 200, 240]]])

如果我告诉它对j维求和,我得到矩阵乘积np.dot(B,V)

In [709]: np.einsum('ij,jk->ik',B,V)                                            
Out[709]: 
array([[ 90, 120, 150],
       [190, 260, 330]])

答案 1 :(得分:0)

上述问题的解决方案是:

out = np.tensordot(b, v, 1)