这里是python的新手。我有以下示例数组:
a = [0,0,1,1,0,0,1,1,2,2,3,3,4,4,0,0]
我想根据连续出现的唯一值来标记和切片数组,即连续出现的相同元素将被分配相同的标签,否则将被分配不同的标签。这样做是为了完成而不需要zeros
分隔来分配不同的标签,就像scipy.ndimage.label之类的那样。
因此,scipy.ndimage.label
的输出不是我所期望的:
lbl = label(a)
lbl = [0,0,1,1,0,0,2,2,2,2,2,2,2,2,0,0]
如您所见,它将[...,1,1,2,2,3,3,4,4,...]
的整个序列组合为一个标签,而不是四个唯一标签。而我想要的是这样的:
lbl = [0,0,1,1,0,0,2,2,3,3,4,4,5,5,0,0]
我是否遗漏了该功能的某些内容,还是有其他方法可以做到这一点?
答案 0 :(得分:0)
方法#1:这是一种方法 -
def label_based_on_shifts(a):
# Detect starts of each label(element is non-zero and is different
# from the previous element)
mask = np.r_[a[0]!=0,(a[1:] != a[:-1]) & (a[1:] !=0)]
# Setup id array, which when cumulatively summed would lead us to
# labelled islands
out = mask.astype(np.uint64).cumsum()
# Set the islands that are zeros in input array to be zeros in o/p too
out[a==0] = 0
return out
示例运行 -
In [53]: a
Out[53]: array([0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 0, 0])
In [54]: label_based_on_shifts(a)
Out[54]: array([0, 0, 1, 1, 0, 0, 2, 2, 3, 3, 4, 4, 5, 5, 0, 0])
方法#2:另一个用np.cumsum
替换np.repeat
-
def label_based_on_shifts_v2(a):
mask = np.r_[True,(a[1:] != a[:-1]),True]
idx = np.flatnonzero(mask)
valid_idx_mask = a[idx[:-1]]!=0
starts = idx[:-1][valid_idx_mask]
stops = idx[1:][valid_idx_mask]
lens = stops-starts
out = np.zeros(len(a), dtype=int)
out[a!=0] = np.repeat(np.arange(1,len(starts)+1), lens)
return out