Алгоритм:
- изменить массив на одно измерение
- получить индекс сортировки с помощью argsort ()
- получить отсортированную версию массива измерений как sorted_A
- используйте where () и diff (), чтобы найти позицию изменения метки в sorted_A
- , используйте позицию изменения и индекс сортировки, чтобы получить исходную позицию метки в одном измерении.
- вычисляет двухмерное местоположение из позиции измерения.
для большого массива, такого как (7000, 9000), это может закончить вычисление за 30 секунд.
здеськод:
import numpy as np
A = np.array([[ 1, 1, 0, 3, 3],
[ 1, 1, 0, 0, 0],
[ 1, 0, 0, 2, 2],
[ 1, 0, 2, 2, 2]] )
def label_range(A):
from itertools import izip_longest
h, w = A.shape
tmp = A.reshape(-1)
index = np.argsort(tmp)
sorted_A = tmp[index]
pos = np.where(np.diff(sorted_A))[0]+1
for p1,p2 in izip_longest(pos,pos[1:]):
label_index = index[p1:p2]
y = label_index // w
x = label_index % w
x0 = np.min(x)
x1 = np.max(x)+1
y0 = np.min(y)
y1 = np.max(y)+1
label = tmp[label_index[0]]
yield label,x0,y0,x1,y1
for label,x0,y0,x1,y1 in label_range(A):
print "%d:(%d,%d)-(%d,%d)" % (label, x0,y0,x1,y1)
#B = np.random.randint(0, 100, (7000, 9000))
#list(label_range(B))