# Rank filter on an nXm array using python

I would like to apply a rank filter on an nXm numpy array. Let's say I have this array:

a = np.random.randint(100,size=(5,5))

array([[ 9, 71, 55, 72, 43],
[46, 56, 44, 17, 64],
[53, 51, 17, 71, 36],
[12, 28, 97, 46, 35],
[29, 55, 27, 48,  5]])


I would like to run a rank filter (kernel window of 3X3) that will give each central pixel in the kernel a value\rank (from 1-9 because it is a 3X3 window) according its position in the histogram. The largest number will get the value of 9 and the lowest number will get the value of 1. For example, the value 56 in position 1,1 will get the value 8 because according to its 8 neighbors, it is the second largest number. The value 44 in position 1,2 will get the value of 3 because it is the 3rd lowest number, there are only two values below it both are 17. (let's ignore for now the edges issues and the tied values issues).

I found that scipy.stats.rankdata can achieve my desired results but the problem is that it is not a convolved filter, meaning, that it works on the entire array and not according to a kernel method, also it gives an output of a 1Xm array, meaning that it does not keep the original nXm array shape.

So I think I need somehow to use this scipy.stats.rankdata filter as a moving kernel of a size of my choise.

I know that scipy has convolve methods such as ndimage.convolve, which I used in the past, and this method works as a running kernel window. But I can't figure out how to combine them in order to get a "proper" kernel ranking filter.

I also saw that scipy has scipy.ndimage.filters.rank_filter but I don't understand how the ranking is actually work there.