Обобщение векторного внешнего произведения: примените его к каждому столбцу матрицы

У меня есть матрица A = [x1, x2, ..., xm] где каждый xi является вектором столбца размера [n, 1], Так что А имеет форму [n, m], Я пытаюсь найти ковариационную матрицу каждого вектора столбца, чтобы, если в результате получилась другая матрица C, C имеет форму [n, n, m] а также C[:,:,i] = np.outer(xi, xi),

Может кто-нибудь сказать мне, как сделать вышеупомянутое, или указать мне на тензорную операцию, которую я должен проверить?

1 ответ

Так что ваши outer цикл выдает:

In [1147]: A = np.arange(12).reshape(3,4)
In [1148]: [np.outer(A[:,i],A[:,i]) for i in range(4)]
Out[1148]: 
[array([[ 0,  0,  0],
        [ 0, 16, 32],
        [ 0, 32, 64]]), array([[ 1,  5,  9],
        [ 5, 25, 45],
        [ 9, 45, 81]]), array([[  4,  12,  20],
        [ 12,  36,  60],
        [ 20,  60, 100]]), array([[  9,  21,  33],
        [ 21,  49,  77],
        [ 33,  77, 121]])]

stacking что в новом 1-м измерении производит:

In [1149]: np.stack(_)
Out[1149]: 
array([[[  0,   0,   0],
        [  0,  16,  32],
        [  0,  32,  64]],
    ....
        [ 21,  49,  77],
        [ 33,  77, 121]]])
In [1150]: _.shape
Out[1150]: (4, 3, 3)    # wrong order - can be transposed.

stack Позвольте нам указать другую ось:

In [1153]: np.stack([np.outer(A[:,i],A[:,i]) for i in range(4)],2)
Out[1153]: 
array([[[  0,   1,   4,   9],
        [  0,   5,  12,  21],
        [  0,   9,  20,  33]],

       [[  0,   5,  12,  21],
        [ 16,  25,  36,  49],
        [ 32,  45,  60,  77]],

       [[  0,   9,  20,  33],
        [ 32,  45,  60,  77],
        [ 64,  81, 100, 121]]])

np.einsum делает это также хорошо:

In [1151]: np.einsum('mi,ni->mni',A,A)
Out[1151]: 
array([[[  0,   1,   4,   9],
        [  0,   5,  12,  21],
        [  0,   9,  20,  33]],

       [[  0,   5,  12,  21],
        [ 16,  25,  36,  49],
        [ 32,  45,  60,  77]],

       [[  0,   9,  20,  33],
        [ 32,  45,  60,  77],
        [ 64,  81, 100, 121]]])
In [1152]: _.shape
Out[1152]: (3, 3, 4)

Трансляция умножения тоже приятно

In [1156]: A[:,None,:]*A[None,:,:]
Out[1156]: 
array([[[  0,   1,   4,   9],
        [  0,   5,  12,  21],
      ...
        [ 32,  45,  60,  77],
        [ 64,  81, 100, 121]]])
Другие вопросы по тегам