如何将for-loop推向numpy

时间:2013-09-23 11:24:43

标签: python numpy kriging

我有以下代码完全符合我的要求(它是克里金方法的一部分)。但问题是它太慢了,我想知道是否有任何选择将for-loop推向numpy?如果我推出numpy.sum,并在那里使用轴参数,它会加速一点点,但显然这不是瓶颈。关于我如何能够将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

2 个答案:

答案 0 :(得分:5)

你可以用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)

答案 1 :(得分:3)

您基本上是在GRZVV的每一行,在末尾添加1,将其与GinvVV相乘,然后将向量中的所有元素相加。如果你没有做“附加1”的事情,你可以做所有没有循环:

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

甚至:

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

我们如何处理额外的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))