Умножение двумерного массива на правильный масштабер индекса в другом двумерном массиве - PullRequest
0 голосов
/ 30 марта 2019

При попытке умножить массив на

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 ]

1 голос
/ 30 марта 2019

То, что вы хотите, является внешним продуктом.

Просто для удовольствия, я буду придерживаться ваших строк, но создам 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)

Тогдаесли я использую broadcasting и plus (что для строк равно 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]])
0 голосов
/ 30 марта 2019

Решение вышеуказанной проблемы:

out = np.tensordot(b, v, 1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...