#python #arrays #numpy
Вопрос:
Учитывая два массивных массива формы (25, 2)
, и (2,)
их можно легко умножить на:
import numpy as np
a = np.random.rand(2, 25)
b = np.random.rand(2)
(a.T * b).T # ok, shape (2, 25)
У меня аналогичная ситуация , когда b
есть форма (2, 4)
, и я хотел бы получить те же результаты, что и выше, для всех «4» b
. Следующие работы,
a = np.random.rand(25, 2)
b = np.random.rand(2, 4)
c = np.moveaxis([a * bb for bb in b.T], -1, 0) # shape (2, 4, 25)
но у меня есть предчувствие, что это возможно и без moveaxis
этого .
Есть какие-нибудь идеи?
Ответ №1:
In [185]: a = np.random.rand(2, 25)
...: b = np.random.rand(2)
Умножение возможно с помощью broadcasting
:
In [186]: a.shape
Out[186]: (2, 25)
In [187]: a.T.shape
Out[187]: (25, 2)
In [189]: (a.T*b).shape
Out[189]: (25, 2)
(25,2) * (2,) => (25,2) * (1,2) => (25,2). Транспонирование-это a moveaxis
, изменение результата на (2,25)
В вашем втором случае.
In [191]: c = np.moveaxis([a * bb for bb in b.T], -1, 0)
In [192]: c.shape
Out[192]: (2, 4, 25)
In [193]: np.array([a * bb for bb in b.T]).shape
Out[193]: (4, 25, 2)
b.T
есть (4,2), так bb
же как и (2,); с (25,2) a
, производит (25,2), как указано выше. добавьте в (4,) итерацию.
(25,1,2) * (1,4,2) => (25,4,2), который может быть перенесен в (2,4,25)
In [195]: (a[:,None]*b.T).shape
Out[195]: (25, 4, 2)
In [196]: np.allclose((a[:,None]*b.T).T,c)
Out[196]: True
(2,4,1) * (2,1,25) => (2,4,25)
In [197]: (b[:,:,None] * a.T[:,None]).shape
Out[197]: (2, 4, 25)
In [198]: np.allclose((b[:,:,None] * a.T[:,None]),c)
Out[198]: True
Ответ №2:
Альтернатива с numpy.einsum
:
np.einsum('ij,jk->jki', a, b)
Результаты проверки совпадают:
(np.einsum('ij,jk->jki', a, b) == c).all()
True