numpy协方差计算(einsum势能?)



我正试图为下面的例子编写一个协方差计算,我知道必须有比for循环更好的方法。我已经研究了np.dot、np.einsum,我觉得np.einsom有能力,但我只是缺少一些实现它的东西。

import numpy as np
# this is mx3
a = np.array([[1,2,3],[4,5,6]])
# this is x3
mean = a.mean(axis=0)
# result should be 3x3
b = np.zeros((3,3))
for i in range(a.shape[0]):
b = b + (a[i]-mean).reshape(3,1) * (a[i]-mean)
b
array([[4.5, 4.5, 4.5],
[4.5, 4.5, 4.5],
[4.5, 4.5, 4.5]])

所以这对于2个数据点样本来说是好的,但对于m=大的数字来说,这是非常慢的。必须有更好的方法。有什么建议吗?

In [108]: a = np.array([[1,2,3],[4,5,6]])
...: # this is x3
...: mean = a.mean(axis=0)
...: 
...: # result should be 3x3
...: b = np.zeros((3,3))
...: for i in range(a.shape[0]):
...:     b = b + (a[i]-mean).reshape(3,1) * (a[i]-mean)
...: 
In [109]: b
Out[109]: 
array([[4.5, 4.5, 4.5],
[4.5, 4.5, 4.5],
[4.5, 4.5, 4.5]])
In [110]: a.mean(axis=0)
Out[110]: array([2.5, 3.5, 4.5])

由于平均值被减去两次,因此我们定义一个新的变量。在这种情况下,2d和1d维度广播,所以我们可以简单地:

In [111]: a1= a - a.mean(axis=0)
In [112]: a1
Out[112]: 
array([[-1.5, -1.5, -1.5],
[ 1.5,  1.5,  1.5]])

其余为正常dot产品:

In [113]: a1.T@a1
Out[113]: 
array([[4.5, 4.5, 4.5],
[4.5, 4.5, 4.5],
[4.5, 4.5, 4.5]])

CCD_ 2和CCD_。

最新更新