我正在尝试将双重求和公式转换为代码,但无法找出正确的矩阵/矢量表示形式.
第一个求和是i到n,第二个求和是j>它在.
我想这里有一个效率更高的& pythonic的编写方式?
我求助于嵌套循环,以使其正常工作,但正如预期的那样,它在大型数据集下运行非常缓慢:
def wapc_denom(weights, vols):
x = []
y = []
for i, wi in enumerate(weights):
for j, wj in enumerate(weights):
if j > i:
x.append(wi * wj * vols[i] * vols[j])
y.append(np.sum(x))
return np.sum(y)
编辑:
使用smci答案的指导,我认为我有一个潜在的解决方案:
def wapc_denom2(weights, vols):
return np.sum(np.tril(np.outer(weights, vols.T)**2, k=-1))
解决方法:
假设您只希望对每一项进行计数(为此您必须将x = []移到外循环中),一种便宜的计算总和的方法是
创建模拟数据
weights = np.random.random(10)
vols = np.random.random(10)
做计算
wv = weights * vols
result = (wv.sum()**2 - wv@wv) / 2
检查是否相同
def wapc_denom(weights, vols):
y = []
for i, wi in enumerate(weights):
x = []
for j, wj in enumerate(weights):
if j > i:
x.append(wi * wj * vols[i] * vols[j])
y.append(np.sum(x))
return np.sum(y)
assert np.allclose(result, wapc_denom(weights, vols))
为什么行得通?
我们正在做的是计算完整矩阵的总和,减去对角线并除以二.这很便宜,因为很容易验证外部乘积的总和是否是总和的乘积.