Умножьте 1D массивы a [k] и d [j] в матрицу m [j, k] - PullRequest
0 голосов
/ 02 мая 2018
>>> import numpy as np

Предположим, у меня есть следующие два массива

>>> a = np.array([a1,a2,a3,a4,a5])
>>> d = np.array([d1,d2,d3])

Я хотел бы знать, как управлять двумя массивами, чтобы получить матрицу 5x3:

>>> m
   np.array([[a1*d1, a2*d1, a3*d1, a4*d1, a5*d1],
             [a1*d2, a2*d2, a3*d2, a4*d2, a5*d2],
             [a1*d3, a2*d3, a3*d3, a4*d3, a5*d3])
>>> m.shape
   (3, 5)

Мне не удалось найти подходящую функцию numpy для достижения этой цели. Даже если окончательная матрица выходит транспонированной.

Ответы [ 3 ]

0 голосов
/ 02 мая 2018

Мне нравится ответ @ P.Camilleri . Это только ради разнообразия ...

>>> import numpy as np
>>> x,y = np.random.random(5), np.random.random(3)      
>>> x
array([0.5538738 , 0.31099761, 0.42709952, 0.28999541, 0.76811293])
>>> y
array([0.80281963, 0.31063054, 0.20141215])

>>> np.array([x])*np.array([y]).T
array([[0.44466076, 0.24967499, 0.34288388, 0.23281401, 0.61665614],
       [0.17205012, 0.09660536, 0.13267015, 0.09008143, 0.23859933],
       [0.11155691, 0.0626387 , 0.08602303, 0.0584086 , 0.15470727]])
0 голосов
/ 03 мая 2018

Несколько таймингов:

>>> from timeit import timeit
>>> 
>>> kwds = dict(globals=globals(), number=10000)
>>> 
>>> a = np.random.random(100)
>>> d = np.random.random(60)
>>>
>>> timeit("d[:, None] * a", **kwds)
0.10106271505355835
>>> timeit("d[:, None] @ a[None]", **kwds)
0.08171644899994135
>>> timeit("np.dot(d[:, None], a[None])", **kwds)
0.08377223135903478
>>> timeit("d.reshape(-1, 1) * a", **kwds)
0.11084615904837847
>>> timeit("np.einsum('i,j->ij', d, a)", **kwds)
0.0618918058462441
>>> timeit("np.tensordot(d, a, ((),()))", **kwds)
0.23450013296678662
>>> timeit("np.c_[d] * a", **kwds)
0.19284361507743597
>>> timeit("np.multiply(*np.ix_(d, a))", **kwds)
0.16771024512127042
>>> timeit("np.multiply.outer(d, a)", **kwds)
0.09988314099609852
>>> timeit("np.outer(d, a)", **kwds)
0.11399263981729746

einsum выглядит быстрее всего.

0 голосов
/ 02 мая 2018

вам нужно использовать трансляцию:

a[None, :] * d[:, None]


In [2]: a = np.arange(5)

In [3]: d = np.arange(3)

In [4]: a[None, :] * d[:, None]
Out[4]: 
array([[0, 0, 0, 0, 0],
       [0, 1, 2, 3, 4],
       [0, 2, 4, 6, 8]])

Вы можете использовать np.newaxis вместо None, он делает то же самое (np.newaxis - это просто псевдоним с более явным именем). Для чего нужно добавить дополнительную ось к a или d:

In [5]: a[None, :].shape
Out[5]: (1, 5)

Broadcasting - очень эффективный инструмент для выполнения операций с массивами в numpy, подробнее об этом в документе .

Как замечание, a * d[:, None] также будет работать, но я считаю, что первая формулировка будет более явной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...