将 numpy 数组转换为范围

DMi*_*Min 0 python arrays numpy list python-3.x

我有一个经过排序的数字列表:

[ 1,  2,  3,  4,  6,  7,  8,  9, 14, 15, 16, 17, 18, 25, 
 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 38, 45]
Run Code Online (Sandbox Code Playgroud)

我想知道 numpy 是否有一个内置功能可以从中得到类似的东西:

[ [1, 4], [6, 9], [14, 18], [25,36], [38], [45] ]
Run Code Online (Sandbox Code Playgroud)

如果它可以忽略中间缺失的某些 2-3 个数字的漏洞,仍然会进入范围,那就太好了。

我基本上列出了要处理的视频的帧号 - 因此,我不会列出所有帧号,而是将其放入范围内,如果中间缺少 3-4 帧也没关系。

只是想知道是否有一些东西已经实现了这个逻辑,因为这似乎是人们想做的常见事情 - 否则,我会自己实现它。

编辑: 发现一个已经回答的非常接近的问题: 将整数列表转换为 python 中的范围

小智 5

由于它被标记为 numpy,因此这里是一个 numpy 解决方案(某种程度上)。没有本机 numpy 函数,但您可以使用diff+ where+ split+ 列表理解:

>>> [[ary[0], ary[-1]] if len(ary)>1 else [ary[0]] for ary in np.split(arr, np.where(np.diff(arr) != 1)[0] + 1)]
[[1, 4], [6, 9], [14, 18], [25, 36], [38], [45]]
Run Code Online (Sandbox Code Playgroud)

如果数组很大,使用循环比使用循环更有效np.split,因此您可以使用下面的函数,它会产生与上面相同的结果:

def array_to_range(arr):
    idx = np.r_[0, np.where(np.diff(arr) != 1)[0]+1, len(arr)]
    out = []
    for i,j in zip(idx, idx[1:]):
        ary = arr[i:j]
        if len(ary) > 1:
            out.append([ary[0], ary[-1]])
        else:
            out.append([ary[0]])
    return out
Run Code Online (Sandbox Code Playgroud)