如何修改Numpy数组特定元素:保留3x3及以上连续1,其余1置0
处理NumPy数组中的连续1区域
输入数组
import numpy as np data=np.array([[4,4,4,0,1,1,1,1,1,1,0,0,0,0,1], [3,0,1,0,1,1,1,1,1,1,1,1,1,1,0], [6,0,0,0,1,1,1,1,1,1,1,1,1,1,0], [2,0,0,0,1,1,1,0,1,0,1,1,1,0,0], [2,0,1,0,1,1,1,0,1,0,1,0,1,0,0]])
需求
在data数组中,仅保留由元素1构成的3x3及更大的连续正方形区域,其余所有1替换为0,非1元素保持不变。
预期输出
[[4 4 4 0 1 1 1 1 1 1 0 0 0 0 0] [3 0 0 0 1 1 1 1 1 1 1 1 1 0 0] [6 0 0 0 1 1 1 1 1 1 1 1 1 0 0] [2 0 0 0 1 1 1 0 0 0 1 1 1 0 0] [2 0 0 0 1 1 1 0 0 0 0 0 0 0 0]]
当前尝试代码
from scipy.ndimage import binary_erosion, binary_dilation # 原代码缺少该导入 k = np.ones((3,3)) print(k) jk = binary_dilation(binary_erosion(data==1, k), k) print(jk)
当前输出(中文翻译)
[[False False False False True True True True True True False False False False False] [False False False False True True True True True True True True True False False] [False False False False True True True True True True True True True False False] [False False False False True True True False False False True True True False False] [False False False False True True True False False False False False False False False]]
最终解决方案
你当前的代码已经通过开闭运算(先腐蚀后膨胀)得到了正确的掩码矩阵jk,这个矩阵中True的位置就是需要保留的1的区域。接下来只需将原数组中的1根据掩码替换,非1元素保持原样:
from scipy.ndimage import binary_erosion, binary_dilation import numpy as np data=np.array([[4,4,4,0,1,1,1,1,1,1,0,0,0,0,1], [3,0,1,0,1,1,1,1,1,1,1,1,1,1,0], [6,0,0,0,1,1,1,1,1,1,1,1,1,1,0], [2,0,0,0,1,1,1,0,1,0,1,1,1,0,0], [2,0,1,0,1,1,1,0,1,0,1,0,1,0,0]]) # 生成掩码:标记需要保留的1的位置 k = np.ones((3,3)) mask = binary_dilation(binary_erosion(data == 1, k), k) # 应用掩码:仅保留mask为True的1,其余1替换为0 result = np.where((data == 1) & mask, data, np.where(data == 1, 0, data)) print(result)
运行这段代码即可得到预期输出,核心逻辑:
- 用
data == 1提取所有1的位置; - 开闭运算后的
mask筛选出属于3x3及更大连续正方形的1; - 通过
np.where实现替换规则:是1且在掩码区域则保留,是1但不在掩码区域则设为0,其他元素保持不变。
内容的提问来源于stack exchange,提问作者Bhar Jay
相关产品推荐
相关产品推荐

