求Python实现一维/二维数组非零连通块(含对角线)计数方法与内置函数
一维/二维非零元素连通块计数问题解答
1. 你的一维方法无法直接用于二维场景
一维思路仅处理了线性的左右相邻关系,但二维场景下的连通性需要覆盖上下、左右以及四个对角线方向的相邻元素,原有的遍历逻辑完全无法适配这种多方向的连通判断,直接套用会得到错误的计数结果。
2. 支持对角线连通的二维连通块计数实现
手动实现(无第三方依赖)
通过BFS或DFS遍历数组,遇到未标记的非零元素时,标记所有与之8连通(含对角线)的元素,每完成一次遍历就累加一个连通块计数。
import numpy as np from collections import deque def count_patches_2D_8connect(array): arr = np.asarray(array) rows, cols = arr.shape visited = np.zeros_like(arr, dtype=bool) patch_count = 0 # 定义8个方向的偏移量 dirs = [(-1,-1), (-1,0), (-1,1), (0,-1), (0,1), (1,-1), (1,0), (1,1)] for i in range(rows): for j in range(cols): if arr[i,j] != 0 and not visited[i,j]: patch_count += 1 # BFS标记连通区域 q = deque([(i,j)]) visited[i,j] = True while q: x, y = q.popleft() for dx, dy in dirs: nx, ny = x+dx, y+dy if 0 <= nx < rows and 0 <= ny < cols: if arr[nx, ny] != 0 and not visited[nx, ny]: visited[nx, ny] = True q.append((nx, ny)) return patch_count # 测试示例 print(count_patches_2D_8connect([[1,0],[1,1]])) # 输出1 print(count_patches_2D_8connect([[1,0],[0,1]])) # 输出1
用scipy简化实现
Python标准库没有内置函数,但scipy.ndimage.label可以快速实现,通过指定结构元素来启用8连通规则:
import numpy as np from scipy.ndimage import label, generate_binary_structure def count_patches_2D_scipy(array): arr = np.asarray(array) # 生成8连通的结构模板:参数2表示二维,2表示连通阶数(8连通) structure = generate_binary_structure(2, 2) _, num_patches = label(arr, structure=structure) return num_patches # 测试示例 print(count_patches_2D_scipy([[1,0],[1,1]])) # 输出1 print(count_patches_2D_scipy([[1,0],[0,1]])) # 输出1
3. Python标准库没有对应内置函数
Python自带的标准库中没有专门用于统计非零元素8连通块的函数。如果不能使用第三方库,就用上面的手动BFS/DFS实现;如果可以引入scipy,ndimage.label是最高效的选择,它还支持切换为4连通(仅上下左右)的规则。
内容的提问来源于stack exchange,提问作者hwerner
相关产品推荐
相关产品推荐

