如何将forloop推到numpy

2024-05-19 00:21:09 发布

您现在位置:Python中文网/ 问答频道 /正文

下面的代码正是我想要的(它是kriging方法的一部分)。但问题是它的速度太慢了,我想知道是否有任何选择可以将for循环向下推到numpy?如果我把数字总和,使用轴参数,它会加快一点,但显然这不是瓶颈。有什么想法可以让我把forloop推到numpy来加速,或者用其他方法来加速吗?)在

# n = 2116
print GRZVV.shape  # (16309, 2116)
print GinvVV.shape  # (2117, 2117) 
VVg = numpy.empty((GRZVV.shape[0]))

for k in xrange(GRZVV.shape[0]):
    GRVV = numpy.empty((n+1, 1))
    GRVV[n, 0] = 1
    GRVV[:n, 0] = GRZVV[k, :]
    EVV = numpy.array(GinvVV * GRVV)  # GinvVV is numpy.matrix
    VVg[k] = numpy.sum(EVV[:n, 0] * VV)

我贴出了ndarrays n矩阵的维数来清理一些东西

编辑:VV的形状是2116


Tags: 方法代码numpyforkriging速度emptyprint
2条回答

基本上是取GRZVV的每一行,在末尾附加一个1,将其与GinvVV相乘,然后将向量中的所有元素相加。如果不执行“append 1”操作,则可以在不使用循环的情况下完成所有操作,如下所示:

VVg = np.sum(np.dot(GinvVV[:, :-1], GRZVV.T), axis=-1) * VV

甚至:

^{pr2}$

我们如何处理额外的1?好吧,从矩阵乘法得到的向量会增加GinvVV[:, -1]中的相应值,当你把它们都加起来,这个值就会增加np.sum(GinvVV[:, -1])。因此,我们只需计算一次,然后将其添加到返回向量中的所有项目中:

VVg = (np.einsum('ij,kj->k', GinvVV[:-1, :-1], GRZVV) + np.sum(GinvVV[:-1, -1])) * VV

如果VV是标量,则上面的代码可以工作。如果它是一个形状(n,)的数组,则以下操作将起作用:

GinvVV = np.asarray(GinvVV)
VVgbis = (np.einsum('ij,kj->k', GinvVV[:-1, :-1]*VV[:, None], GRZVV) +
          np.dot(GinvVV[:-1, -1], VV))

您可以执行以下操作来代替k循环(运行时间~3s):

tmp = np.concatenate((GRZVV, np.ones((16309,1),dtype=np.double)), axis=1)
EVV1 = np.dot(GinvVV, tmp.T)
#Changed line below based on *askewchan's* recommendation
VVg1 = np.sum(np.multiply(EVV1[:n,:],VV[:,np.newaxis]), axis=0)

相关问题 更多 >

    热门问题