Как мне умножить строки в одном массиве numpy на несколько столбцов во втором массиве? - PullRequest
1 голос
/ 25 апреля 2020

У меня есть numpy вопрос

У меня есть двумерный массив значений

vals=np.array([[1.0, 2.0, 3.0],[4.0, 5.0, 6.0],[7.0, 8.0, 9.0]], np.float32)

И двумерный массив масштабных коэффициентов

factors=np.array([[1.0, 4.0], [2.0, 5.0], [3.0, 6.0]])

Я хочу умножить каждую строку в vals на каждую строку в коэффициентах, чтобы в итоге получить массив «scaled_vals», как показано ниже. ПРИМЕЧАНИЕ. Этот вывод был исправлен из моего первоначального поста - мои извинения за эту ошибку up

[[ 1.  2.  3.]
 [ 8. 10. 12.]
 [21. 24. 27.]]
[[ 4.  8. 12.]
 [20. 25. 30.]
 [42. 48. 54.]]

Я показываю факторы только с двумя столбцами данных, но на самом деле это 'n'.

Любая помощь будет с благодарностью получена.

Даг

===

скопировано из комментария:

for step in range(2): 
    scaled_vals = np.multiply(vals, factors[0:,step:step+1])

Ответы [ 4 ]

1 голос
/ 25 апреля 2020

Игра с broadcasting:

vals[:, None, None, :] * factors.T[None, :, :, None]

Вывод:

array([[[[ 1.,  2.,  3.],
         [ 2.,  4.,  6.],
         [ 3.,  6.,  9.]],

        [[ 4.,  8., 12.],
         [ 5., 10., 15.],
         [ 6., 12., 18.]]],


       [[[ 4.,  5.,  6.],
         [ 8., 10., 12.],
         [12., 15., 18.]],

        [[16., 20., 24.],
         [20., 25., 30.],
         [24., 30., 36.]]],


       [[[ 7.,  8.,  9.],
         [14., 16., 18.],
         [21., 24., 27.]],

        [[28., 32., 36.],
         [35., 40., 45.],
         [42., 48., 54.]]]])
1 голос
/ 25 апреля 2020

Блок (2,3,3), который вы показываете, может быть создан с:

In [267]: vals[0,:]*factors.T[:,:,None]                                                                
Out[267]: 
array([[[ 1.,  2.,  3.],
        [ 2.,  4.,  6.],
        [ 3.,  6.,  9.]],

       [[ 4.,  8., 12.],
        [ 5., 10., 15.],
        [ 6., 12., 18.]]])

, но комментарий l oop равен;

In [268]: for step in range(2):  
     ...:     print(np.multiply(vals, factors[0:,step:step+1])) 
     ...:                                                                                              
[[ 1.  2.  3.]
 [ 8. 10. 12.]
 [21. 24. 27.]]
[[ 4.  8. 12.]
 [20. 25. 30.]
 [42. 48. 54.]]
In [269]: vals*factors.T[:,:,None]                                                                     
Out[269]: 
array([[[ 1.,  2.,  3.],
        [ 8., 10., 12.],
        [21., 24., 27.]],

       [[ 4.,  8., 12.],
        [20., 25., 30.],
        [42., 48., 54.]]])
0 голосов
/ 25 апреля 2020

Вы можете использовать einsum один вкладыш (без l oop), чтобы умножить ваши индексы в любой форме, которую вы пожелаете:

output = np.einsum('ij,kl->ilkj',vals,factors)

это умножает [i,j] с vals на [k,l] от factors и поместите его в [i,l,k,j] на выходе. Обратите внимание, что ответ @Quan Hoang (upvoted) делает то же самое без зацикливания. Тем не менее, это несколько более читабельно, я думаю, и вы можете расширить его на любую другую комбинацию, какую пожелаете.

output:

[[[[ 1.  2.  3.]
   [ 2.  4.  6.]
   [ 3.  6.  9.]]

  [[ 4.  8. 12.]
   [ 5. 10. 15.]
   [ 6. 12. 18.]]]


 [[[ 4.  5.  6.]
   [ 8. 10. 12.]
   [12. 15. 18.]]

  [[16. 20. 24.]
   [20. 25. 30.]
   [24. 30. 36.]]]


 [[[ 7.  8.  9.]
   [14. 16. 18.]
   [21. 24. 27.]]

  [[28. 32. 36.]
   [35. 40. 45.]
   [42. 48. 54.]]]]

UPDATE: при каждом умножении, упомянутом в комментариях, решение будет :

output = np.einsum('ij,ik->kij',vals,factors)

это умножает [i,j] от значений до [i,k] от факторов и ставит его на [k,i,j] в выходе.

вывод:

[[[ 1.  2.  3.]
  [ 8. 10. 12.]
  [21. 24. 27.]]

 [[ 4.  8. 12.]
  [20. 25. 30.]
  [42. 48. 54.]]]
0 голосов
/ 25 апреля 2020

Единственное, что я могу понять в отношении входов и выходов, - это если вы умножаете каждую строку значений на соответствующий индекс всех факторов, но вам необходимо соответствовать размерам факторов и значений.

import numpy as np

vals=np.array([[1.0, 2.0, 3.0],[4.0, 5.0, 6.0],[7.0, 8.0, 9.0]], np.float32) # shape = mxn

print(vals.shape)

factors=np.array([[1.0, 4.0], [2.0, 5.0], [3.0, 6.0]]) # shape = nxk increasing dim to match with vals.shape

m = vals.shape[0]
n = vals.shape[1]
k = factors.shape[1]

print(factors.shape)



result = np.array([np.array([vals[j]*np.repeat(factors[:,i], n).reshape(n,n) for i in range(k)]) for j in range(m)])

print(result[0])

(3, 3)
(3, 2)
[[[ 1.  2.  3.]
  [ 2.  4.  6.]
  [ 3.  6.  9.]]

 [[ 4.  8. 12.]
  [ 5. 10. 15.]
  [ 6. 12. 18.]]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...