用矢量化双重求和的Pythonic方法

我正在尝试将双重求和公式转换为代码,但无法找出正确的矩阵/矢量表示形式.

第一个求和是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))

为什么行得通?

我们正在做的是计算完整矩阵的总和,减去对角线并除以二.这很便宜,因为很容易验证外部乘积的总和是否是总和的乘积.

上一篇:python – numpy数组中的多个累积和


下一篇:numpy求解无循环的3d线性方程