我需要计算一个矩阵列表的总和,但是,我不能使用np.sum
,即使使用axis=0
,我也不知道为什么。目前的解决方案是循环,但有更好的方法吗?
import numpy as np
SAMPLE_SIZES = [10, 100, 1000, 10000]
ITERATIONS = 1
MEAN = np.array([1, 1])
COVARIANCE = np.array([[1, 0.5], [0.5, 1]])
for sample_size in SAMPLE_SIZES:
max = -1
for i in range(ITERATIONS):
xs = np.random.multivariate_normal(MEAN, COVARIANCE, size=sample_size)
sigma = [[0, 0], [0, 0]]
for x in xs:
sigma += np.outer((x-MEAN), (x-MEAN)) / (sample_size-1)
在上面的代码中,我可以使用一些numpy
函数替换最后一个循环吗?我想如果数据非常大,使用循环效率会不高。
答案 0 :(得分:3)
了解numpy broadcasting。
xs = np.random.multivariate_normal(MEAN, COVARIANCE, size=sample_size)
xs
现在具有形状(sample_size, 2)
,这意味着您可以直接减去MEAN
。现在,您需要在xs - MEAN
和xs - MEAN
之间添加外部产品,同时添加sample_size
轴。最好使用np.einsum
:
>>> sigma = np.einsum('ij,ik->jk', xs - MEAN, xs - MEAN) / sample_size
>>> sigma
array([[ 1.00216043, 0.49549231],
[ 0.49549231, 1.00004423]])
另一种方法是使用广播:
>>> sigma = np.sum((xs - MEAN)[:, :, np.newaxis]
* (xs - MEAN)[:, np.newaxis, :], axis=0) / sample_size
虽然广播解决方案似乎更容易理解,但np.einsum
通常比more efficient广播。
附加说明:请注意,我除以sample_size
,而不是sample_size - 1
。这是因为为了估计具有已知均值的随机变量的协方差矩阵,您需要除以sample_size
。当您从同一数据集估算平均值时使用sample_size - 1
,并在协方差估计中使用它。否则你的协方差估计会有偏差。
答案 1 :(得分:0)
如果您只是想计算经验协方差,那么我建议使用numpy.cov(xs.T)
。
否则,最后3行可以替换为:
xm = xs - np.mean(xs, axis=0)
sigma = np.inner(xm.T. xm.T) / (sample_size-1)