Hadamard произведение массивов неравномерной формы - PullRequest
0 голосов
/ 06 мая 2019

Я делаю целую кучу продуктов Hadamard, как часть проекта машинного обучения.Чтобы прояснить проблему, ниже приведена настройка:

# shape: (2, 3)
In [17]: arr1
Out[17]: 
array([[0.44486617, 0.21001534, 0.63833794],
       [0.90878526, 0.61692562, 0.01978946]])

# shape: (5, 3)
In [18]: arr2
Out[18]: 
array([[0.00640485, 0.22768134, 0.62845291],
       [0.58168743, 0.65527711, 0.14765079],
       [0.61389269, 0.38546809, 0.62696518],
       [0.73977707, 0.03737199, 0.45905132],
       [0.51932163, 0.00119124, 0.07241033]])

Теперь я хочу выполнить произведение адамара каждой из строк в arr1 с помощью arr2 и, таким образом, получить результирующий массив, вызвать егоres, формы (10, 3).

 (2, 3)
  *  | 
 (5, 3)
   ||
 (10,3)

Как мы можем сделать это с минимальными накладными расходами, используя только NumPy?

1 Ответ

1 голос
/ 06 мая 2019

Мы можем использовать broadcasting после расширения одного из массивов до 3D -

(a[:,None]*b).reshape(-1,a.shape[1]) # a,b are input arrays

Для больших массивов, для достижения эффективности памяти при многоядерном использовании и, следовательно,производительность, мы можем использовать numexpr модуль -

import numexpr as ne

ne.evaluate('a3D*b',{'a3D':a[:,None]}).reshape(-1,a.shape[1])

Время -

In [20]: a = np.random.rand(200,30)

In [21]: b = np.random.rand(500,30)

In [22]: %timeit (a[:,None]*b).reshape(-1,a.shape[1])
100 loops, best of 3: 4.61 ms per loop

In [27]: %timeit ne.evaluate('a3D*b',{'a3D':a[:,None]}).reshape(-1,a.shape[1])
100 loops, best of 3: 2.28 ms per loop
...