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

numpy中无循环获取聚类标注数组内各元素坐标的实现方法

无循环实现方案

纯NumPy向量化实现(无额外依赖)

核心思路是先批量提取所有非零标签的坐标及对应标签值,再通过排序和分界点拆分得到每个标签的坐标组,全程无逐标签遍历数组的高开销循环,性能远高于逐标签调用np.where:

import numpy as np
from scipy.ndimage import label

# 原有标注逻辑
input_array = np.array([[0, 1, 1, 0],
                        [1, 1, 0, 0],
                        [0, 0, 0, 1],
                        [0, 0, 0, 1]])
labeled_array, num_labels = label(input_array)

# 无循环获取各标签坐标逻辑
# 1. 提取所有非零元素的坐标,形状为(N,2),每行对应(行索引, 列索引)
coords = np.argwhere(labeled_array > 0)
# 2. 获取每个坐标对应的标签值
labels = labeled_array[coords[:, 0], coords[:, 1]]
# 3. 按标签值排序
sorted_idx = np.argsort(labels)
sorted_labels = labels[sorted_idx]
sorted_coords = coords[sorted_idx]
# 4. 定位不同标签的分界位置
split_points = np.where(np.diff(sorted_labels) != 0)[0] + 1
# 5. 拆分坐标组并转为目标字典格式
coord_groups = np.split(sorted_coords, split_points)
result = {label: group.tolist() for label, group in zip(np.unique(labels), coord_groups)}

运行后result输出和你要求的格式完全一致:

{1: [[0, 1], [0, 2], [1, 0], [1, 1]], 2: [[2, 3], [3, 3]]}

可选:Pandas简化实现

如果允许引入pandas依赖,代码可以更简洁:

import pandas as pd

coords = np.argwhere(labeled_array > 0)
df = pd.DataFrame(coords, columns=['y', 'x'])
df['label'] = labeled_array[coords[:,0], coords[:,1]]
result = df.groupby('label').agg(list).apply(tuple, axis=1).to_dict()

效率说明

  • 逐标签调用np.where的时间复杂度为O(M*N),M为标签数量,N为数组元素总数,标签越多性能下降越明显
  • 上述向量化方案时间复杂度为O(N log N),仅和数组总大小相关,和标签数量无关,标签数超过10个时性能就会显著超过循环方案,数组尺寸越大、标签越多优势越明显。
  • 最后生成字典的推导式仅对标签级别的少量数据操作,开销可以忽略,不属于影响性能的循环逻辑。

内容的提问来源于stack exchange,提问作者Canol Gökel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 20:36:03