数字 1 和 0 的数据检测器
Data detector for number 1 and 0
我有一个仅包含 0 和 1 的数据集。我想要一个检测器来查找 1 的起始位置和 1 的结束位置,然后 return 将与它们的索引相关的内容分别放入不同的列表.所以我写了一些代码如下:
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))
然而,当我 运行 上面的代码时,它 return 如下所示,这不是我想要的输出。
([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]。
如果有人知道如何解决这个问题,请告诉我。赞赏!!
一个问题当然是,您不更改标志。
== 是比较运算符,不会为 flag
赋新值
您也可以尝试使用 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指正
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)
打印:
[[1, 22, 34], [5, 29, 38]]
使用 enumerate
to get positions of 1
s and zip
查找连续 1
的序列 starts/ends
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
开始(当它们自然从 0
开始时)[=26],我们可以指定 enumerate
的 start
参数=]
ones_positions = [position
for position, value in enumerate(n, start=1)
if value == 1]
之后
>>>ones_starts
[1, 22, 34]
>>>ones_ends
[4, 28, 38]
最后我们可以把它写成函数:
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])
因为@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,然后打印结果。
此解决方案还使用了较少的内存,因为它使用了生成器。
我有一个仅包含 0 和 1 的数据集。我想要一个检测器来查找 1 的起始位置和 1 的结束位置,然后 return 将与它们的索引相关的内容分别放入不同的列表.所以我写了一些代码如下:
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))
然而,当我 运行 上面的代码时,它 return 如下所示,这不是我想要的输出。
([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]。
如果有人知道如何解决这个问题,请告诉我。赞赏!!
一个问题当然是,您不更改标志。 == 是比较运算符,不会为 flag
赋新值您也可以尝试使用 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指正
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)
打印:
[[1, 22, 34], [5, 29, 38]]
使用 enumerate
to get positions of 1
s and zip
查找连续 1
的序列 starts/ends
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
开始(当它们自然从 0
开始时)[=26],我们可以指定 enumerate
的 start
参数=]
ones_positions = [position
for position, value in enumerate(n, start=1)
if value == 1]
之后
>>>ones_starts
[1, 22, 34]
>>>ones_ends
[4, 28, 38]
最后我们可以把它写成函数:
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])
因为@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,然后打印结果。
此解决方案还使用了较少的内存,因为它使用了生成器。