2017-06-19 23 views
0

我有一个数据集包含只有0和1.我想有一个检测器来找到哪里1开始和哪里1结束,然后返回与其索引相关的东西到不同的列表每。所以,我已经写了一些代码如下:数字检测器为1号和0号

n= [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 
    1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1] 

def detector (data): 
    x = 0 
    start = [] 
    end = [] 
    for index, i in enumerate(data): 
     if x == 0 and i == 1: 
      start.append((index+1)) 
      x == 1 
     elif x == 1 and i==0: 
       end.append((index)) 
       x == 0 
    return start, end 

print (detector(n)) 

然而,当我运行上面的代码,它返回象下面这样,这不是我想要的输出。

([1, 2, 3, 4, 22, 23, 24, 25, 26, 27, 28, 34, 35, 36, 37, 38], []) 

我的期望的输出是如下:

([1, 22, 34], [4,28,38]) 

正如你可以看到上述情况,START_TIME应该[1,22,34]和END_TIME应该[4,28,38]。

如果有人知道如何解决问题,请让我知道。感谢!

回答

1

一个问题是肯定的,你不改变标志。 ==是比较运算,并且不新的值赋给标志

+0

哦,你能解释一下如何改变国旗的价值吗?我想如果我能改变它,那么我的问题就会解决。 – ryan9025

+0

'flag = 1'而不是'flag == 1'。你的代码然后工作,除了捕获最后的end_time – tom

+0

但是当我做'flag = 1',它给我一个语法错误? – ryan9025

0

你也可以使用GROUPBY尝试:

import itertools 
L = [[y[0] for y in it] 
    for x,it in 
    itertools.groupby(enumerate(n),lambda x: x[1]) 
    ][::2] 
res = [x[0] for x in L],[x[-1] for x in L] 

您可以在不使用索引的一个更加正确的解决方案可能到达。

感谢vishes_shell用于校正

+0

产量与OP的预期不同。 –

+0

是的,我应该更仔细地阅读OP需要的内容。这个想法是使用groupby而不是显式索引。我会编辑它。谢谢 – Ben

0
n = [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 
    1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1] 

prev_num = 0 

starts = [] 
ends = [] 
result = (starts, ends) 

for idx, num in enumerate(n): 
    if prev_num == 0 and num == 1: 
     starts.append(idx + 1) 
    elif prev_num == 1 and num == 0: 
     ends.append(idx + 1) 
    elif num == 1 and idx == (len(n) - 1): 
     ends.append(idx + 1) 
    prev_num = num 

print(result) 

它打印:使用enumerate得到的1 S和zip位置

[[1, 22, 34], [5, 29, 38]] 
1

发现当连续1 S初始/的序列结束

ones_positions = [position 
        for position, value in enumerate(n) 
        if value == 1] 
ones_starts = [ones_positions[0]] + [ 
    next_position 
    for position, next_position in zip(ones_positions, 
             ones_positions[1:]) 
    if next_position - position > 1] 
ones_ends = [position 
      for position, next_position in zip(ones_positions, 
               ones_positions[1:]) 
      if next_position - position > 1] + [ones_positions[-1]] 

给我们

>>>ones_starts 
[0, 21, 33] 
>>>ones_ends 
[3, 27, 37] 

,如果你希望你的指数从1

>>>ones_starts 
[1, 22, 34] 
>>>ones_ends 
[4, 28, 38] 
后开始(当它们自然地从 0开始)

ones_positions = [position 
        for position, value in enumerate(n, start=1) 
        if value == 1] 

我们可以指定enumeratestart参数

最后我们可以把它写成函数:

def detector(data, target_value=1): 
    positions = [position 
       for position, value in enumerate(data, start=1) 
       if value == target_value] 
    start_times = [positions[0]] + [ 
     next_position 
     for position, next_position in zip(positions, 
              positions[1:]) 
     if next_position - position > 1] 
    end_times = [position 
       for position, next_position in zip(positions, 
                positions[1:]) 
       if next_position - position > 1] + [positions[-1]] 
    return start_times, end_times 

和测试

n = [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 
    1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1] 
print(detector(n)) 

给我们

([1, 22, 34], [4, 28, 38]) 
0

由于@DanielChristiany指出你在哪里你的错误了。我将介绍您我的解决方案,它比任何的呈现更快(至少正常工作):

edges = (index for index, i in enumerate(n[1:], 1) if i != n[index-1]) 
if n[0] == 1: 
    edges = (1, *edges) 
if n[-1] == 1: 
    some = (*edges, len(n)) 
print(edges[::2], edges[1::2]) 

基本上它首先搜索边缘,其中元件的变化从0到1或从1到0。然后检查是否第一最后的元素是1,然后打印结果。

该解决方案由于使用了生成器,因此也使用更少的内存。