You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从NumPy数组中高效提取同值区域聚类的实现方案(解决递归方法的性能与栈溢出问题)

高效提取NumPy数组中同值聚类的方案

针对你遇到的递归方法效率低、栈溢出的问题,我推荐使用scikit-image库中的区域分析工具——这是计算机视觉领域处理掩码区域分割的标准方案,完全基于矩阵操作,高效且不易出错。

实现步骤

1. 预处理:将字符串格式数据转为NumPy数组

首先把你给出的字符串列表转换成数值型的NumPy数组,方便后续处理:

import numpy as np
from skimage import measure

# 你的示例数据
data_str = [
    "01110000000000000000000000",
    "00111110000222222220000000",
    "01110000000222222200000000",
    "00000000000222000000000000",
    "00000000000000000000000000",
    "00000000000000000000000000",
    "00003333300000000000000000",
    "00003333322222000000000000",
    "00000000022222000000000000",
    "00000000000000222000000000",
    "00000000000000222000000000",
    "00000000000000000000000000",
    "00000000000000000000000000",
    "00000000000000000000000000",
    "00000000000000000000000000",
    "00000000000000000000000000"
]

# 转换为NumPy数值数组
arr = np.array([list(s) for s in data_str], dtype=int)

2. 标记连通区域并提取聚类

使用measure.label标记所有非零连通区域,再通过measure.regionprops提取每个区域的坐标和对应数值:

# 标记连通区域:connectivity=2表示8连通,=1表示4连通,可按需调整
label_img = measure.label(arr, background=0, connectivity=2)

# 存储最终聚类结果:键是聚类的数值,值是该数值下所有聚类的坐标列表
clusters = {}

# 遍历每个标记的区域
for region in measure.regionprops(label_img, intensity_image=arr):
    # 获取区域的数值(因为每个聚类仅含相同数字,取第一个像素的值即可)
    val = region.intensity_mean  # 由于区域内值相同,均值等于实际值
    val = int(val)
    
    # 获取区域所有像素的坐标((行, 列)格式)
    coords = list(zip(region.coords[:, 0], region.coords[:, 1]))
    
    # 按数值分组存储
    if val not in clusters:
        clusters[val] = []
    clusters[val].append(coords)

3. 查看结果

打印结果就能看到每个数值对应的所有聚类坐标:

# 输出2的所有聚类
print("数值2的聚类:")
for idx, cluster in enumerate(clusters[2], 1):
    print(f"聚类{idx}: {cluster}")

# 输出3的所有聚类
print("\n数值3的聚类:")
for idx, cluster in enumerate(clusters[3], 1):
    print(f"聚类{idx}: {cluster}")

方案优势

  • 高效稳定:基于底层矩阵运算,比递归快几个数量级,完全避免栈溢出问题;
  • 灵活可控:可通过connectivity参数选择4连通或8连通的区域判定规则;
  • 成熟可靠:scikit-image是计算机视觉领域的主流库,处理掩码区域分割的场景经过大量验证。

备选方案(无scikit-image时)

如果无法安装scikit-image,也可以用OpenCV的connectedComponentsWithStats函数,实现逻辑类似:

import cv2

# 转换为uint8格式(OpenCV要求)
arr_cv = arr.astype(np.uint8)
# 标记连通区域
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(arr_cv, connectivity=8)

clusters_cv = {}
for label in range(1, num_labels):  # 跳过背景(label=0)
    # 获取当前区域的坐标
    coords = np.where(labels == label)
    coords = list(zip(coords[0], coords[1]))
    # 获取区域数值
    val = arr[coords[0][0], coords[0][1]]
    if val not in clusters_cv:
        clusters_cv[val] = []
    clusters_cv[val].append(coords)

内容的提问来源于stack exchange,提问作者Alexey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 21:12:49