I have a 2-D numpy array that can be subdivided into 64 boxes (think of a chessboard). The goal is a function that returns the position and value of the maximum in each box. Something like:
FindRefs(array) --> [(argmaxX00, argmaxY00, Max00), ...,(argmaxX63, argmaxY63, Max63)] where argmaxXnn and argmaxYnn are the indexes of the whole array (not of the box), and Maxnn is the max value in each box. In other words,
Maxnn = array[argmaxYnn,argmaxYnn] I've tryed the obvious "nested-for" solution:
def FindRefs(array): Height, Width = array.shape plumx = [] plumy = [] lum = [] w = int(Width/8) h = int(Height/8) for n in range(0,8): # recorrer boxes x0 = n*w x1 = (n+1)*w for m in range(0,8): y0 = m*h y1 = (m+1)*h subflatind = a[y0:y1,x0:x1].argmax() # flatten index of box y, x = np.unravel_index(subflatind, (h, w)) X = x0 + x Y = y0 + y lum.append(a[Y,X]) plumx.append(X) plumy.append(Y) refs = [] for pt in range(0,len(plumx)): ptx = plumx[pt] pty = plumy[pt] refs.append((ptx,pty,lum[pt])) return refs It works, but is neither elegant nor eficient. So I've tryed this more pythonic version:
def FindRefs(a): box = [(n*w,m*h) for n in range(0,8) for m in range(0,8)] flatinds = [a[b[1]:h+b[1],b[0]:w+b[0]].argmax() for b in box] unravels = np.unravel_index(flatinds, (h, w)) ur = [(unravels[1][n],unravels[0][n]) for n in range(0,len(box))] absinds = [map(sum,zip(box[n],ur[n])) for n in range(0,len(box))] refs = [(absinds[n][0],absinds[n][1],a[absinds[n][1],absinds[n][0]]) for n in range(0,len(box))] return refs It works fine but, to my surprise, is not more efficient than the previous version!
The question is: Is there a more clever way to do the task?
Note that efficiency matters, as I have many large arrays for processing.
Any clue is welcome. :)