Вы можете реализовать свою идею напрямую, используя numpy и scipy.stats.mode
.
Во-первых, найдите расположение значений nan, сравнивая массив с самим собой, потому что число с плавающей запятой NaN не равно самому себе по определению. Функция np.where
вернет все местоположения, выполняемые этим условием, в двух кортежах индексов, один для строк, а другой для столбцов.
Затем для каждого местоположения, в котором найдено NaN, добавьте 8 дельт к чтобы получить окружающие его пиксели. Это можно эффективно сделать с помощью дельта-массива, в котором перечислены все возможные смещения для индекса строки и столбца для каждого соседа.
Наконец, выполните внутреннюю проверку и запустите функцию mode
на выбранном , допустимые соседи и заполните это значение в ячейке NaN.
Вот код, следующий за моим описанием выше:
import numpy as np
import scipy.stats
arr = np.asarray([
0, 1, 1, 1, 0, 1,
1, np.nan, 0, 1, 0, 1,
1, 1, 0, 1, 1, np.nan
]).reshape(3, 6)
delta_rows = np.array([-1, -1, -1, 0, 0, 1, 1, 1])
delta_cols = np.array([-1, 0, 1, -1, 1, -1, 0, 1])
nan_rows, nan_cols = np.where(arr != arr)
for nan_row, nan_col in zip(nan_rows, nan_cols):
neighbour_rows = nan_row + delta_rows
neighbour_cols = nan_col + delta_cols
within_boundary = (
(0 <= neighbour_rows) & (neighbour_rows < arr.shape[0]) &
(0 <= neighbour_cols) & (neighbour_cols < arr.shape[1])
)
neighbour_rows = neighbour_rows[within_boundary]
neighbour_cols = neighbour_cols[within_boundary]
arr[nan_row, nan_col] = scipy.stats.mode(arr[neighbour_rows, neighbour_cols]).mode
После этого мы видим, что каждое значение NaN в arr
правильно заполнен режимом окружающих его ячеек:
>>> print(arr)
[[0. 1. 1. 1. 0. 1.]
[1. 1. 0. 1. 0. 1.]
[1. 1. 0. 1. 1. 1.]]