In [220]: a = np.arange(15).reshape(5,3)
In [221]: a
Out[221]:
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11],
[12, 13, 14]])
При использовании стандартного numpy
вещания:
In [222]: a[:,:,None]*a[:,None,:]
Out[222]:
array([[[ 0, 0, 0],
[ 0, 1, 2],
[ 0, 2, 4]],
[[ 9, 12, 15],
[ 12, 16, 20],
[ 15, 20, 25]],
[[ 36, 42, 48],
[ 42, 49, 56],
[ 48, 56, 64]],
[[ 81, 90, 99],
[ 90, 100, 110],
[ 99, 110, 121]],
[[144, 156, 168],
[156, 169, 182],
[168, 182, 196]]])
In [223]: _.shape
Out[223]: (5, 3, 3)
einsum
было упомянуто:
In [224]: np.einsum('ij,ik->ijk',a,a).shape
Out[224]: (5, 3, 3)
Вещание работает по:
(5,3) => (5,3,1) and (5,1,3) => (5,3,3)
* 1012Индексирование *
None
похоже на
reshape(5,3,1)
, добавление измерения. В трансляции размер 1 соответствует размеру другого массива (ов).
reshape
дешево;используйте его свободно.
tensordot
не очень хорошо назван;«тензор» означает, что он может работать с больше чем 2d (но тогда все numpy могут сделать это). «точка» относится к точечному произведению, сокращению. С einsum
и matmul/@
tensordot
не требуется. И никогда не работал для создания массивов более высокой размерности.