在 Python 中的大阵列中使用 8 像素邻域模式检查并填充中心像素
Checking and infilling the central pixel with 8 pixel neighbourhood mode in a large array in Python
我有一个大的二进制数组(500 x 700)
,我想在其中检查'NaNs
'并用八个周围像素的模式填充中心像素(如果超过 4 个周围像素有 0或 1).它更像是 3x3 滑动 window 搜索。在 xarray 或 scipy.ndimage 甚至 numpy 中是否有任何 tools/functions 可以做到这一点?
例如
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)
arr[1,1] = 1
arr[-1,-1] = 1 (only 3 neighbours)
任何帮助将不胜感激..
提前致谢。
您可以直接使用numpy和scipy.stats.mode
实现您的想法。
首先,通过将数组与自身进行比较来查找 nan 值的位置,因为根据定义,NaN 浮点数不等于自身。 np.where
函数将 return 此条件包含的所有位置,在两个索引元组中,一个用于行,另一个用于列。
然后,对于找到 NaN 的每个位置,将其添加 8 个增量以获得其周围的像素。这可以使用增量数组有效地完成,它列出了每个邻居的行和列索引的所有可能偏移量。
最后,对选定的有效邻居执行 within-boundary 检查和 运行 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
之后,我们可以看到 arr
中的每个 NaN 值都正确填充了其周围单元格的模式:
>>> print(arr)
[[0. 1. 1. 1. 0. 1.]
[1. 1. 0. 1. 0. 1.]
[1. 1. 0. 1. 1. 1.]]
我有一个大的二进制数组(500 x 700)
,我想在其中检查'NaNs
'并用八个周围像素的模式填充中心像素(如果超过 4 个周围像素有 0或 1).它更像是 3x3 滑动 window 搜索。在 xarray 或 scipy.ndimage 甚至 numpy 中是否有任何 tools/functions 可以做到这一点?
例如
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)
arr[1,1] = 1
arr[-1,-1] = 1 (only 3 neighbours)
任何帮助将不胜感激..
提前致谢。
您可以直接使用numpy和scipy.stats.mode
实现您的想法。
首先,通过将数组与自身进行比较来查找 nan 值的位置,因为根据定义,NaN 浮点数不等于自身。 np.where
函数将 return 此条件包含的所有位置,在两个索引元组中,一个用于行,另一个用于列。
然后,对于找到 NaN 的每个位置,将其添加 8 个增量以获得其周围的像素。这可以使用增量数组有效地完成,它列出了每个邻居的行和列索引的所有可能偏移量。
最后,对选定的有效邻居执行 within-boundary 检查和 运行 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
之后,我们可以看到 arr
中的每个 NaN 值都正确填充了其周围单元格的模式:
>>> print(arr)
[[0. 1. 1. 1. 0. 1.]
[1. 1. 0. 1. 0. 1.]
[1. 1. 0. 1. 1. 1.]]