Расширение матрицы до тензора - PullRequest
1 голос
/ 17 октября 2019

У меня есть матрица (m, n), где каждая строка является примером с n функциями. Я хочу расширить его до матрицы (m, n, n), то есть для каждого примера создать внешний продукт его функций. Я изучил tensordot, но не нашел способа сделать это - похоже, он только сокращает тензоры, а не расширяет их.

a = np.arange(5*3).reshape(5, 3, 1)
b = np.arange(5*3).reshape(1, 3, 5)
c = np.tensordot(a, b, axes=([1,2],[1,0]))  # gives a (5,5) matrix
c = np.tensordot(a, b, axes=([1,2],[0,1]))  # throws a shape-mismatch error

Я приведу простой пример дляодин рядСкажем, у вас есть вектор col a = [1, 2, 3], который я хочу получить, это a * a.T т.е.:

1, 2, 3
2, 4, 6
3, 6, 9

1 Ответ

2 голосов
/ 17 октября 2019
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 не требуется. И никогда не работал для создания массивов более высокой размерности.

...