Было бы более согласованно с индексацией Python для nonzero_coords([0, 0, 0, 0, 1, 2, 3, 4])
возвращать (4, 8)
, чем (4, 7)
, потому что [0, 0, 0, 0, 1, 2, 3, 4][4:8]
возвращает [1, 2, 3, 4]
.
Вот функция, которая вычисляет ненулевые интервалы. Он обрабатывает несколько интервалов:
def nonzero_intervals(vec):
'''
Find islands of non-zeros in the vector vec
'''
if len(vec)==0:
return []
elif not isinstance(vec, np.ndarray):
vec = np.array(vec)
edges, = np.nonzero(np.diff((vec==0)*1))
edge_vec = [edges+1]
if vec[0] != 0:
edge_vec.insert(0, [0])
if vec[-1] != 0:
edge_vec.append([len(vec)])
edges = np.concatenate(edge_vec)
return zip(edges[::2], edges[1::2])
Если вы действительно хотите, чтобы в ответ были включены конечные индексы острова, вы можете просто изменить последнюю строку на: return zip(edges[::2], edges[1::2]-1)
Тесты:
a = [0, 0, 0, 0, 1, 2, 3, 4]
intervals = nonzero_intervals(a)
assert intervals == [(4, 8)]
a = [1, 2, 3, 4, 0, 0]
intervals = nonzero_intervals(a)
assert intervals == [(0, 4)]
a=[1, 2, 0, 0, 0, 3, 4, 0]
intervals = nonzero_intervals(a)
assert intervals == [(0, 2), (5, 7)]
a = [0, 4, 0, 6, 0, 6, 7, 0, 9]
intervals = nonzero_intervals(a)
assert intervals == [(1, 2), (3, 4), (5, 7), (8, 9)]
a = [1, 2, 3, 4]
intervals = nonzero_intervals(a)
assert intervals == [(0, 4)]
a = [0, 0, 0]
intervals = nonzero_intervals(a)
assert intervals == []
a = []
intervals = nonzero_intervals(a)
assert intervals == []