将布尔索引转换为运行的开始/结束对

时间:2013-09-16 20:43:46

标签: python numpy

是否有一个numpy函数可以转换像:

[0, 1, 0, 1, 1, 1, 0, 1, 1]

到连续范围的起始/结束对数组,如:

[[1, 2],
 [3, 6],
 [7, 9]]

3 个答案:

答案 0 :(得分:3)

不幸的是我没有安装numpy,但是这个逻辑应该为你做。

import itertools
x = [0, 1, 0, 1, 1, 1, 0, 1, 1]

# get the indices where 1->0 and 0->1
diff = np.diff(x) 
diff_index = diff.nonzero(x)

# pair up the ranges using itertools
def pairwise(iterable):
    a, b = itertools.tee(iterable)
    next(b, None)
    return itertools.izip(a, b)

ranges = pairwise(x)

文档:

numpy diff
numpy nonzero itertools grouper

答案 1 :(得分:2)

与@Serdalis回答相同的原则,但完全依赖于numpy:

def start_end(arr):
    idx = np.nonzero(np.diff(arr))[0] + 1
    if arr[0]:
        idx = np.concatenate((np.array([0], dtype=np.intp), idx))
    if arr[-1]:
        idx = np.concatenate((idx, np.array([len(arr)],
                                            dtype=np.intp),))
    return idx.reshape(-1, 2)

>>> start_end([1,1,1,0,0,1,0])
array([[0, 3],
       [5, 6]], dtype=int64)
>>> start_end([0,1,1,1,0,0,1])
array([[1, 4],
       [6, 7]], dtype=int64)
>>> start_end([0,1,1,1,0,0,1,0])
array([[1, 4],
       [6, 7]], dtype=int64)
>>> start_end([1,1,1,0,0,1])
array([[0, 3],
       [5, 6]], dtype=int64)

答案 2 :(得分:1)

def find_starts_ends(x):
    temp = [0]
    temp.extend(x)
    temp.append(0)
    diffs = np.diff(temp)
    ends = np.where(diffs == -1)[0]
    starts = np.where(diffs == 1)[0]
    return np.vstack((starts, ends)).T

结果:

>>> find_starts_ends(a)
array([[1, 2],
       [3, 6],
       [7, 9]])
>>> find_starts_ends([1,1,0,0,1,1])
array([[0, 2],
       [4, 6]])