import numpy as np
a = np.array([True, False, True, True, True, False, True, True])
#Indices are found here
a_true_ranges = np.argwhere(np.diff(a,prepend=False,append=False))
#Conversion into list of 2-tuples
a_true_ranges = a_true_ranges.reshape(len(a_true_ranges)//2,2)
a_true_ranges = [tuple(r) for r in a_true_ranges]
a_true_ranges
#[(0, 1), (2, 5), (6, 8)]
def find_contigs(mask):
"""
Find contiguous regions in a mask that are True with no False in between
"""
assert len(mask.shape) == 1 # 1D tensor of bools
contigs = []
found_contig = False
for i,b in enumerate(mask):
if b and not found_contig: # found the beginning of a contig
contig = [i]
found_contig = True
elif b and found_contig: # currently have contig, continuing it
pass
elif not b and found_contig: # found the end, record previous index as end, reset indicator
contig.append(i-1)
found_contig = False
contigs.append(tuple(contig))
else: # currently don't have a contig, and didn't find one
pass
# fence post bug - check if the very last entry was True and we didn't get to finish
if b:
contig.append(i)
found_contig = False
contigs.append(tuple(contig))
return contigs
from itertools import groupby
a = np.array([True, False, True, True, True, False, True, True])
i = 0
res = []
for k, g in groupby(a):
l = len(list(g))
if k:
res.append((i,i+l))
i += l
print(res)
# [(0, 1), (2, 5), (6, 8)]
from itertools import groupby
a = np.array([True, False, True, True, True, False, True, True])
def true_indices(a):
i = 0
for k, g in groupby(a):
l = len(list(g))
if k:
yield (i,i+l)
i += l
list(true_indices(a))
# [(0, 1), (2, 5), (6, 8)]
def getConRegions(booleanList):
conRegions=[]
start=-1
for index,item in enumerate(booleanList):
if item and start<0:start=index
elif start>=0 and not item:
conRegions.append((start,index-1))
start=-1
if(start>=0):conRegions.append((start,len(booleanList)-1))
return conRegions
print(getConRegions([True,False,True,True,True,False,True,True]))
list = [True, False, True, True, True, False, True, True]
if list[-1] == True:
list.extend([False])
answers = []
beginning = "yes"
for index, value in enumerate(list):
if value == True and beginning == "yes":
x = index
beginning = "not anymore"
elif value == True:
pass
else:
answers.append((x, index -1))
beginning = "yes"
print(answers)
import numpy as np
def find_contigs(arr):
indices = []
# Each number in this array will be the index of an
# element in 'arr' just *before* it switches
nonzeros = np.nonzero(np.diff(arr))[0]
# Case if array begins with True
if arr[0]:
if len(nonzeros):
indices.append((0, nonzeros[0] + 1))
else:
indices.append((0, len(arr)))
nonzeros = nonzeros[1:]
# Correct for array ending in True
if len(nonzeros) % 2:
final_idx = (nonzeros[-1] + 1, len(arr))
nonzeros = nonzeros[:-1]
else:
final_idx = None
# Parse nonzero indices
nonzeros += 1
nonzeros = nonzeros.reshape((len(nonzeros)//2, 2))
indices.extend([(a, b) for a, b in zip(nonzeros[:, 0], nonzeros[:, 1])])
if final_idx is not None:
indices.append(final_idx)
return indices
7条答案
按热度按时间piv4azn71#
我已经在我写的一个名为haggis的实用程序库中实现了这个功能。函数是
haggis.npy_util.mask2runs
。我写它的部分原因是为了解决堆栈溢出上反复出现的这个问题:字符串
第二列是排他索引,因为这在python和numpy中更有用,所以您可能需要
型
这个函数没有什么特别的。你可以用numpy把它写成一行程序:
型
o2gm4chl2#
这是一个只有一行代码的numpy实现。
适用于输入。我还没有测试过边缘情况,但应该也可以工作
如果你需要代码的到来,干杯:)
字符串
8hhllhi23#
我找到了一个解决方案:
字符串
l5tcr1uw4#
我不确定是否有一个很好的纯Numpy方法来实现这一点,但既然看起来你愿意循环,你可以使用
itertools.groupby
并跟踪索引和组长度:字符串
如果你想要闭区间,显然你可以从第二个元组值中减去1。
你也可以把它写成一个生成器,这样在内存中使用长列表时会更友好一些:
型
dtcbnfnu5#
我对Pytorch不是很熟悉,但这个问题本身看起来很容易解决。你需要遍历整个列表,并存储找到的应急区域的第一个索引。我使用了-1,因为它超出了任何索引的范围。从那里,你只需将一个元组添加到一个包含已保存索引和当前索引的列表中,并将起始索引重置为-1.由于这依赖于找到一个False布尔值,我在循环外添加了一个非重置开始索引的最终检查,这意味着从那里到列表末尾有一个应急区域。
我说的是当前指数,但为了保持它的入站,我减去1,使它更符合你想要的。
字符串
cclgggtu6#
我卑微的解决方案:
字符串
输出:
型
dzjeubhm7#
基于numpy的快速解决方案:
字符串