我有一个numpy二维数组,形状为(2,5)(可以是更大的尺寸(m,n))
A=array([[2.64859009e-02, 2.17771938e-02, 2.38019379e+00, 7.35715883e-01,6.89917290e-01],
[6.89917290e-01, 5.67262659e-01, 6.20004150e+01, 1.91642758e+01,1.79712923e+01]]
我想生成两个5×5的矩阵,这是数组A本身内每个数组的外积。
第一个矩阵应该是[2.64859009e-02, 2.17771938e-02, 2.38019379e+00, 7.35715883e-01,6.89917290e-01]
与[2.64859009e-02, 2.17771938e-02, 2.38019379e+00, 7.35715883e-01,6.89917290e-01]
的外积,第二个矩阵应该是[6.89917290e-01, 5.67262659e-01, 6.20004150e+01, 1.91642758e+01,1.79712923e+01]
与[6.89917290e-01, 5.67262659e-01, 6.20004150e+01, 1.91642758e+01,1.79712923e+01]
的外积。
计算之后,我想对两个5×5矩阵的每个元素求和,最后将其输出为一个5×5矩阵。
A[0] outer* A[0] + A[1] outer* A[1]
在numpy中有快速的方法吗?
答案 0 :(得分:2)
让我们创建一个更简单的测试数组:
In [254]: A = np.arange(10).reshape(2,5)
In [255]: A
Out[255]:
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
In [256]: A.shape
Out[256]: (2, 5)
鉴于描述问题的方式,np.outer
应该易于应用:
In [257]: np.outer(A[0],A[0])+np.outer(A[1],A[1])
Out[257]:
array([[25, 30, 35, 40, 45],
[30, 37, 44, 51, 58],
[35, 44, 53, 62, 71],
[40, 51, 62, 73, 84],
[45, 58, 71, 84, 97]])
np.outer
仅适用于1d数组,不适用于整个2d A
。但是我们可以使用outer
来进行同样类型的broadcasting
。结果将是(2,5,5)数组,然后我们可以在第一个轴上求和:
In [260]: (A[:,:,None]*A[:,None,:]).sum(axis=0)
Out[260]:
array([[25, 30, 35, 40, 45],
[30, 37, 44, 51, 58],
[35, 44, 53, 62, 71],
[40, 51, 62, 73, 84],
[45, 58, 71, 84, 97]])
np.einsum
也是描述这种操作的便捷方式(如果您习惯于处理轴索引):
In [261]: np.einsum('ij,ik->jk',A,A)
Out[261]:
array([[25, 30, 35, 40, 45],
[30, 37, 44, 51, 58],
[35, 44, 53, 62, 71],
[40, 51, 62, 73, 84],
[45, 58, 71, 84, 97]])
但是,einsum
肯定看起来像dot
的产品,是产品的总和。我们只需要转置第一个数组即可:
np.einsum('ji,ik->jk', A.T,A)
或使用np.dot
:
In [262]: np.dot(A.T,A)
Out[262]:
array([[25, 30, 35, 40, 45],
[30, 37, 44, 51, 58],
[35, 44, 53, 62, 71],
[40, 51, 62, 73, 84],
[45, 58, 71, 84, 97]])
答案 1 :(得分:1)
您可以使用here中的np.outer
方法。
A=np.array([[2.64859009e-02, 2.17771938e-02, 2.38019379e+00, 7.35715883e-01,6.89917290e-01],[6.89917290e-01, 5.67262659e-01, 6.20004150e+01, 1.91642758e+01,1.79712923e+01]])
b = np.outer(A[0],A[0])
c = np.outer(A[1],A[1])
简单的b+c
足以完成最后一步。