我希望能够检测numpy数组中连续的1的序列。实际上,我想首先确定数组中的元素是否在至少三个1的序列中。例如,我们有以下数组a:
import numpy as np
a = np.array([1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0])
然后,下面加粗的1是满足要求的元素。
[1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0]
接下来,如果两个由至多两个0分隔的1跨度,则这两个跨度组成更长的跨度。因此,以上数组可以表示为:
[1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0]
换句话说,对于原始输入数组,我希望输出如下:
[True, True, True, True, True, True, True, False, False, False, False, False, True, True, True, True, True, True, True, True, True, True, False]
我一直在考虑一个算法来实现这个功能,但是我想到的所有算法似乎都太复杂了。所以我希望了解更好的实现方式——如果有人能帮助我,我将不胜感激。
更新:
很抱歉我的问题没有表述清楚。我想把数组中3个或更多连续的1识别为1的范围,并且将任何两个只有一个或两个0之间的1范围与分隔0一起识别并作为一个长范围处理。我的目标可以通过以下方式理解:如果1范围之间只有一个或两个0,则将这些0视为错误并应该改正为1。
@ritesht93提供了一个几乎给出我想要的答案。然而,当前答案没有识别出由0分隔的三个1范围,这些范围应该被识别为一个单独的范围。例如,对于以下数组:
a2 = np.array([0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0])
我们应该接收输出。
[False, True, True, True, True, True, True, True, True,
True, True, True, True, True, False, False, False, False,
False, True, True, True, True, True, False]
更新2:
我受到了极大的启发,并发现基于正则表达式的算法最易于实现和理解,尽管我不确定与其他方法相比效率如何。最终我使用了以下方法。
lst = np.array([0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0])
lst1 = re.sub(r'1{3,}', lambda x:'c'*len(x.group()), ''.join(map(str, lst)))
print lst1
识别了一串1的跨度
0ccc0ccc00cccc00100ccccc0
然后将连续的1之间建立连接
lst2 = re.sub(r'c{1}0{1,2}c{1}', lambda x:'c'*len(x.group()), ''.join(map(str, lst1)))
print lst2
这提供了
0ccccccccccccc00100ccccc0
最终结果由以下代码给出:
np.array(list(lst2)) == 'c'
array([False, True, True, True, True, True, True, True, True,
True, True, True, True, True, False, False, False, False,
False, True, True, True, True, True, False])