How to push for-loop before numpy

I have the following code snippet that does exactly what I want (this is part of the kriging method). But the problem is that it is too slow, and I want to know if there is any option to force the for-loop to numpy? If I push numpy.sum and use the axis argument there, it speeds up a bit, but apparently this is not a bottleneck. Any ideas on how I can click on forloop on numpy to speed it up or other ways to speed it up?)

# 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) 

I posted the dimensions of the ndarrays n matrix to clear some things

edit: VV form is 2116

+6
source share
2 answers

You can do the following instead of your loop through k (runtime ~ 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) 
+5
source

Basically you take each line of GRZVV , adding 1 to the end, multiplying it by GinvVV , and then adding all the elements in the vector. If you didn’t do “Addendum 1,” you could do it all without loops like:

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

or even:

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

How do we handle this extra 1? Well, the resulting vector, starting from the matrix multiplication, will increase by the corresponding value in GinvVV[:, -1] , and when you add them, the value will be increased by np.sum(GinvVV[:, -1]) . Therefore, we can simply calculate this once and add it to all elements of the return vector:

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

The above code works if VV is a scalar. If it is an array of the form (n,) , then the following will work:

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

Source: https://habr.com/ru/post/954414/


All Articles