0

I'm having trouble finding a solution to speed up a for loop in python. The following code does exactly what i want but is really slow :


# CoordEtAngle is an array containing 5 columns
# 1, 2 and 3 column are x y z coordinate of a points
# 4 and 5 values corresponding to those points


points=CoordEtAngle[:,0:3]
NumElem=np.zeros((len(allElem)), dtype=int)
CoordAxelist=[]

for idx,elemcur in enumerate(allElem):
    Coord = np.asarray(map(lambda i: allNodes[i].coordinates, elemcur.connectivity)) # gives me an array containing x,y and z coordinate of a box for each elements
    min_x=np.min(Coord[:,0])
    max_x=np.max(Coord[:,0])
    min_y=np.min(Coord[:,1])
    max_y=np.max(Coord[:,1])
    min_z=np.min(Coord[:,2])
    max_z=np.max(Coord[:,2])
    bound_x = np.logical_and(points[:, 0] > min_x, points[:, 0] < max_x)
    bound_y = np.logical_and(points[:, 1] > min_y, points[:, 1] < max_y)
    bound_z = np.logical_and(points[:, 2] > min_z, points[:, 2] < max_z)
    bb_filter = np.logical_and(np.logical_and(bound_x, bound_y), bound_z)
    NumElem[idx]=np.int(elemcur.label)
    CoordAxelist.append([np.mean(CoordEtAngle[bb_filter,3]),np.mean(CoordEtAngle[bb_filter,4])])
    
CoordAxelist=np.concatenate(CoordAxelist)

Thanks in advance for your input. I have a technical issue and i can only use numpy library ...

I did manage to gain some speed using lambda and map in some part of the loop but have no idea how to get even better results

Jvigs
  • 1
  • narrow down your problem, use `line_profiler` to check where is your bottleneck. Done that, create some smaller, **reproducible** example so people here can help you easier and better. – dankal444 Jan 24 '23 at 14:41

1 Answers1

-1

I have several suggestions for you to try:

  1. Try to pre allocate CoordAxelist before your loop starts
  2. Try replacing enumerate with numpy.ndenumerate
  3. You can profile your code with cProfile. You can read how to use this profiling tool in this question
Timur Khr
  • 15
  • 5
  • 1
    1) Pre-allocating `CoordAxelist` is *meaningless*; the cost of shuffling a few pointers around for amortized `list` growth is *nothing* relative to any meaningful amount of work being done here. 2) `enumerate`'s overhead is so low I doubt you'd notice a single cycle saved by replacing it (is `allElem` even a `numpy` array that might benefit from it?). In short: All your specific suggestions are *tiny* micro-optimizations that won't affect the speed of this code in any discernible way. – ShadowRanger Jan 21 '23 at 14:28