Одним из возможных подходов может быть определение функции, которая заменяет центральное значение режимом ...
import numpy as np
from scipy.ndimage import generic_filter
def most_frequent(x):
central = x[x.size//2]
values, counts = np.unique(x, return_counts=True)
max_freq = counts.max()
modes = values[counts == max_freq]
if central in modes:
return central
else:
return modes[0]
... и передачу такой функции в scipy.ndimage.generic_filter
.
Демо
In [143]: r = 2
In [144]: block_size = (2*r + 1, 2*r + 1)
In [145]: block_size
Out[145]: (5, 5)
In [146]: np.random.seed(329)
In [147]: arr = np.random.randint(low=0, high=10, size=(6, 8), dtype=np.uint8)
In [148]: arr
Out[148]:
array([[9, 6, 2, 2, 0, 5, 6, 4],
[9, 7, 0, 2, 0, 5, 4, 2],
[1, 3, 8, 1, 4, 6, 5, 2],
[5, 1, 7, 8, 5, 7, 0, 2],
[8, 1, 0, 5, 4, 5, 4, 5],
[4, 1, 5, 3, 6, 9, 4, 3]], dtype=uint8)
In [149]: generic_filter(arr, function=most_frequent,
...: size=block_size, mode='constant', cval=np.nan)
...:
Out[149]:
array([[9, 2, 2, 2, 0, 2, 4, 5],
[9, 1, 0, 2, 0, 2, 5, 2],
[1, 1, 0, 5, 5, 5, 5, 5],
[1, 1, 1, 5, 5, 5, 4, 5],
[1, 1, 1, 5, 5, 5, 4, 5],
[1, 1, 5, 5, 5, 5, 4, 4]], dtype=uint8)
Обратите внимание, что запуск этого кода в массиве 9085 & times; 10852 может занять некоторое время.