Python:删除多个for循环以加快计算(以l2为中心)

Python:删除多个for循环以加快计算(以l2为中心),python,Python,我需要计算的方程式如下: (式中,nexp是样本点的数量,ndv是这种情况下的设计变量数量) 问题是,如果我使用三个for循环来计算右边的第三个项,那么对于大数据量来说显然太慢了(我有大小为(390625 x 1000)的数据) 我已经设法将循环减少到只有一个,但是,对于如此庞大的数据,计算速度仍然不够快(到目前为止,我管理的代码是: def CL2(x): '''Centered L2 discrepancy''' nexp, ndv = x.shape t

我需要计算的方程式如下:

(式中,nexp是样本点的数量,ndv是这种情况下的设计变量数量)

问题是,如果我使用三个for循环来计算右边的第三个项,那么对于大数据量来说显然太慢了(我有大小为(390625 x 1000)的数据)

我已经设法将循环减少到只有一个,但是,对于如此庞大的数据,计算速度仍然不够快(到目前为止,我管理的代码是:

def CL2(x):
    '''Centered L2 discrepancy'''    
    nexp, ndv = x.shape

    term3 = 0
    term2 = np.sum(np.prod(1. + np.abs(x - 0.5)/2 - np.abs(x - 0.5)**2/2, axis = 1))        
    for i in range(nexp):
        term3 = term3 + np.sum(np.prod(1. + np.abs(x[i,:] - 0.5)/2 + np.abs(x - 0.5)/2 - np.abs(x[i,:] - x)/2, axis = 1))
    CL2 = (13/12)**ndv - (2*term2 - term3/nexp)/nexp    

    return CL2
循环中的计算似乎太复杂了。我也尝试过使用三维矩阵(通过广播),但由于矩阵的尺寸越来越大,速度甚至比以前慢

不管有多少for循环来计算这个方程,但我真的需要它足够快,至少比现在快


我找不到numpy.prod的任何替代方案,这可能是导致计算时间过长的原因。

通过引入

 y_ik = 1/2 (x_ik - 1/2)
然后,双倍和中的项变为

1 + |y_ik| + |y_jk| - |y_ik - y_jk|
如果y_-ik和y_-jk的符号是相反的,那么这等于一,所以我们可以去掉所有这些项。如果符号相同,它等于

1 + 2 min(|y_ik|, |y_jk|)
这也比原来的术语简单

注意到另一个和中的项相等

(1 + 2 |y_ik|) (1 - |y_ik|)
通过预计算,我们可以节省更多的钱

z_ik = 1 + 2 |y_ik| = 1 + |x_ik - 1/2|
(缺点:我们仍然需要记住y_-ik的符号)

然后,双倍和中的项变为

min(z_ik, z_jk)
如果y_ik和y_jk的符号相同,并且如果符号不同,则可以省略

另一笔款项中的条款变为

1/2 z_ik (3 - z_ik)

如果你创建一个
0.5*np.abs(x-0.5)的矩阵,你会获得多少收益
你能给我举一个最小的例子,让我可以运行计时并演示如何使它更快吗?@ssm创建一个单独的矩阵总是会使整个代码花费更多的时间,这在这种情况下也是如此。@JoonatanSamuel我实际上只需要创建一个足够大的x,种子x=np.rand.rand(50000,100)并将其放入函数中。时间是用“time”模块计算的。@CodyChung:不确定为什么会是这样。你已经做了很多次了。理论上,如果你使用一个伪变量
x1=0.5*np.abs(x-0.5),你应该会获得一些时间
并执行一次,而不是在循环中执行多次。虽然进行这样的修改似乎很好,但我不认为这将如何删除计算的for循环,因为它仍然需要单独计算x_ik(或x_jk)。