I have an 2-D array that I want to find the max value per row and then find the next max-value that is not within +/- n of the previous value. For example I have the following matrix:
results = array([[ 33, 108, 208, 96, 96, 112, 18, 208, 33, 323, 60, 42], [ 51, 6, 39, 112, 160, 144, 342, 195, 27, 136, 42, 54], [ 12, 176, 266, 162, 45, 70, 156, 198, 143, 56, 342, 130], [ 22, 288, 304, 162, 21, 238, 156, 126, 165, 91, 144, 130], [342, 120, 36, 51, 10, 128, 156, 272, 32, 98, 192, 288]]) row_max_index = results.argmax(1) row_max_index #show max index array([ 9, 6, 10, 2, 0])
Now I’d like to get the next max value not within say +/- 2 of the current max.
Here is what I have but it feels sloppy:
maskIndx = np.c_[row_max_index-2, row_max_index-1, row_max_index, row_max_index+1, row_max_index+2,]%12 maskIndx #show windowed index array([[ 7, 8, 9, 10, 11], [ 4, 5, 6, 7, 8], [ 8, 9, 10, 11, 0], [ 0, 1, 2, 3, 4], [10, 11, 0, 1, 2]]) results[np.meshgrid(np.arange(5), np.arange(5))[1], maskIndx] = 0 #uses array indexing results #show results array([[ 33, 108, 208, 96, 96, 112, 18, 0, 0, 0, 0, 0], [ 51, 6, 39, 112, 0, 0, 0, 0, 0, 136, 42, 54], [ 0, 176, 266, 162, 45, 70, 156, 198, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 238, 156, 126, 165, 91, 144, 130], [ 0, 0, 0, 51, 10, 128, 156, 272, 32, 98, 0, 0]]) next_max_index = results.argmax(1) array([2, 9, 2, 5, 7])
Any ideas on doing this faster through indexing/windowing?
Advertisement
Answer
You can create a mask around the indices you compute for the max by taking an array of indices and subtracting the relevant max_indices, and then use the masked api to recompute the argmax:
import numpy as np result = ... # Result here row_max_index = results.argmax(axis=1, keepdims=True) indices = np.arange(results.shape[1]) mask = np.abs(indices - row_max_index) <= 2 out = np.ma.array(results, mask=mask).argmax(axis=1)