Python: optimising loops -


i wish optimise python code consisting of 2 nested loops. not familar numpy, understand should enable me improve efficiency such task. below test code wrote reflects happens in actual code. using numpy range , iterator slower usual python one. doing wrong? best solution problem?

thanks help!

import numpy import time  # setup problem analagous in real code npoints_per_plane = 1000 nplanes = 64 naxis = 1000 npoints3d = naxis + npoints_per_plane * nplanes npoints = naxis + npoints_per_plane specres = 1000  # data being mapped sol = dict() sol["ems"] = numpy.zeros(npoints3d) sol["abs"] = numpy.zeros(npoints3d)  # non-random input data data = dict() data["ems"] = numpy.zeros((npoints,specres)) data["abs"] = numpy.zeros((npoints,specres)) ip in range(npoints):     data["ems"][ip,:] = numpy.random.random(specres)[:]     data["abs"][ip,:] = numpy.random.random(specres)[:] ems_mod = numpy.random.random(1)[0] abs_mod = numpy.random.random(1)[0] ispec = numpy.random.randint(specres)  # code want optimize  t0 = time.time()  # usual python range , iterator ip in range(npoints_per_plane):     jp = naxis + ip     ipl in range(nplanes):         ip3d = jp + npoints_per_plane * ipl         sol["ems"][ip3d] = data["ems"][jp,ispec] * ems_mod         sol["abs"][ip3d] = data["abs"][jp,ispec] * abs_mod  t1 = time.time()  # numpy ranges , iterator ip_vals = numpy.arange(npoints_per_plane) ipl_vals = numpy.arange(nplanes) ip in numpy.nditer(ip_vals):     jp = naxis + ip     ipl in numpy.nditer(ipl_vals):         ip3d = jp + npoints_per_plane * ipl         sol["ems"][ip3d] = data["ems"][jp,ispec] * ems_mod         sol["abs"][ip3d] = data["abs"][jp,ispec] * abs_mod   t2 = time.time()  print "plain python: %0.3f seconds" % ( t1 - t0 ) print "numpy: %0.3f seconds" % ( t2 - t1 ) 

edit: put "jp = naxis + ip" in first loop only

additional note:

i worked out how numpy inner loop, not outer loop:

# numpy vectorization ip in xrange(npoints_per_plane):     jp = naxis + ip     sol["ems"][jp:jp+npoints_per_plane*nplanes:npoints_per_plane] = data["ems"][jp,ispec] * ems_mod     sol["abs"][jp:jp+npoints_per_plane*nplanes:npoints_per_plane] = data["abs"][jp,ispec] * abs_mod 

joe's solution below shows how both together, thanks!

the best way of writing loops in numpy not writing loops , instead using vectorized operations. example:

c = 0 in range(len(a)):     c += a[i] + b[i] 

becomes

c = np.sum(a + b, axis=0) 

for a , b shape of (100000, 100) takes 0.344 seconds in first variant, , 0.062 seconds in second.

in case presented in question following want:

sol['ems'][naxis:] = numpy.ravel(     numpy.repeat(         data['ems'][naxis:,ispec,numpy.newaxis] * ems_mod,         nplanes,         axis=1     ),     order='f' ) 

this further optimized some tricks, reduce clarity , premature optimization because:

plain python: 0.064 seconds

numpy: 0.002 seconds

the solution works follows:

your original version contains jp = naxis + ip merely skips first naxis elements [naxis:] selects first naxis elements. inner loop repeats value of data[jp,ispec] nplanes times , writes multiple locations ip3d = jp + npoints_per_plane * ipl equivalent flattened 2d array offset naxis. therefore second dimension added via numpy.newaxis (previously 1d) data['ems'][naxis:, ispec], values repeated nplanes times along new dimension via numpy.repeat. resulting 2d array flattened again via numpy.ravel (in fortran order, i.e., lowest axis having smallest stride) , written appropriate subarray of sol['ems']. if target array 2d, repeat skipped using automatic array broadcasting.

if run situation cannot avoid using loops, use cython (which supports efficient buffer views on numpy arrays).


Comments

Popular posts from this blog

How to mention the localhost in android -

php - Calling a template part from a post -

c# - String.format() DateTime With Arabic culture -