查找连续的重复项并列出它们在python中出现的位置的索引

时间:2019-02-08 16:47:23

标签: python python-3.x numpy

例如,我在python中有一个列表:

mylist = [1,1,1,1,1,1,1,1,1,1,1,
        0,0,1,1,1,1,0,0,0,0,0,
        1,1,1,1,1,1,1,1,0,0,0,0,0,0]

我的目标是找到连续存在五个或更多零的位置,然后列出发生此位置的索引,例如,此输出为:

[17,21][30,35]

以下是我在其他问题中尝试过/看到的内容:

def zero_runs(a):
    # Create an array that is 1 where a is 0, and pad each end with an extra 0.
    iszero = np.concatenate(([0], np.equal(a, 0).view(np.int8), [0]))
    absdiff = np.abs(np.diff(iszero))
    # Runs start and end where absdiff is 1.
    ranges = np.where(absdiff == 1)[0].reshape(-1, 2)
    return ranges

    runs = zero_runs(list)

这给出了输出:

[0,10]
[11,12]
...

这基本上只是列出所有重复项的索引,我将如何将这些数据分离成我需要的内容

4 个答案:

答案 0 :(得分:2)

您可以使用itertools.groupby,它将标识列表中的连续组:

from itertools import groupby

lst = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0]

groups = [(k, sum(1 for _ in g)) for k, g in groupby(lst)]

cursor = 0
result = []
for k, l in groups:
    if not k and l >= 5:
        result.append([cursor, cursor + l - 1])
    cursor += l

print(result)

输出

[[17, 21], [30, 35]]

答案 1 :(得分:2)

您当前的尝试非常接近。它返回数组中所有连续零的游程,因此您要做的就是添加一个检查以过滤出少于5个连续零的游程。


def threshold_zero_runs(a, threshold):
    iszero = np.concatenate(([0], np.equal(a, 0).view(np.int8), [0]))
    absdiff = np.abs(np.diff(iszero))
    ranges = np.where(absdiff == 1)[0].reshape(-1, 2)

    m = (np.diff(ranges, 1) >= threshold).ravel()
    return ranges[m] 

array([[17, 22],
       [30, 36]], dtype=int64)

答案 2 :(得分:0)

在阵列上使用generateTokenWithCompletionHandler运算符。将转换后的版本与原始版本进行比较。如果它们不匹配匹配,那么您需要进行过渡。然后,您只需确定相隔至少5个位置的相邻过渡即可。

你能从那里拿走吗?

答案 3 :(得分:0)

使用itertools.groupbyenumerate的另一种方式。

首先找到零和索引:

from operator import itemgetter
from itertools import groupby

zerosList = [
    list(map(itemgetter(0), g)) 
    for i, g in groupby(enumerate(mylist), key=itemgetter(1)) 
    if not i
]
print(zerosList)
#[[11, 12], [17, 18, 19, 20, 21], [30, 31, 32, 33, 34, 35]]

现在只需过滤zerosList

runs = [[x[0], x[-1]] for x in zerosList if len(x) >= 5]
print(runs)
#[[17, 21], [30, 35]]