矢量外积的推广:将其应用于矩阵的每一列

时间:2017-08-23 23:53:18

标签: python numpy matrix matrix-multiplication tensor

我有一个矩阵A = [x1, x2, ..., xm],其中每个xi是一个大小为[n, 1]的列向量。所以A的形状为[n, m]。我试图找到每个列向量的协方差矩阵,这样如果结果是另一个矩阵CC的形状为[n, n, m]C[:,:,i] = np.outer(xi, xi)

有人可以告诉我如何在numpy中执行上述操作或指向我应该检查的张量操作吗?

1 个答案:

答案 0 :(得分: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在新的第一维上产生:

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]]])