怎么才能return最长连续出现的"True"布尔值,把其他的True换成False呢?
How can i return the longest continuous occurrence of "True" in Boolean, and replace other True with False?
我正在尝试 return 一个只给出原始布尔值中最长 "True" 出现的布尔值,并将较短的 "True" 块替换为 "False"。示例 a=[True, True, False, True , True, True, False],我想 return [False, False, False, True, True, True, False].
我试过 more_itertools 它似乎有一些有趣的功能,但不确定如何准确地实现我的目的。
a=[True, True, False, True , True, True, False]
pred = lambda x: x in {True}
p=list(mit.run_length.encode(a))
>>>
Results in: (True,2),(False,1),(True,3),(False,1)
所以我想最终自动得到的是(False,3),(True,3),(False,1)。有什么建议么?
感谢您的帮助
以下解决方案在使用 more_itertools.run_length 后应该有效。
本质上,逻辑是找到True的最长子序列的长度,以及该索引在result
列表中的位置
然后计算最长子序列前后的元素总数,然后相应地构造结果元组列表。
import more_itertools as mit
a=[True, True, False, True , True, True, False]
result = list(mit.run_length.encode(a))
#Find the length of longest subsequence of True, and the location if that index in result
max_true_count = -1
max_true_idx = -1
for idx, (val, count) in enumerate(result):
if val and max_true_count < count:
max_true_count = count
max_true_idx = idx
#Find total elements before and after the longest subsequence tuple
elems_before_idx = sum((idx[1] for idx in result[:max_true_idx]))
elems_after_idx = sum((idx[1] for idx in result[max_true_idx+1:]))
#Create the output list using the information
output = [(False, elems_before_idx), (True, max_true_count), (False, elems_after_idx)]
print(output)
输出将是
[(False, 3), (True, 3), (False, 1)]
这是一个矢量化的 -
def keep_longest_true(a):
# Convert to array
a = np.asarray(a)
# Attach sentients on either sides w.r.t True
b = np.r_[False,a,False]
# Get indices of group shifts
s = np.flatnonzero(b[:-1]!=b[1:])
# Get group lengths and hence the max index group
m = (s[1::2]-s[::2]).argmax()
# Initialize array and assign only the largest True island as True.
out = np.zeros_like(a)
out[s[2*m]:s[2*m+1]] = 1
return out
def island_info(a):
'''' Get island tuple info
'''
# Attach sentients on either sides w.r.t array start and end
b = np.r_[~a[0],a,~a[-1]]
# Get group lengths and group start elements
lens = np.diff(np.flatnonzero(b[:-1] != b[1:]))
grpID = np.resize([a[0],~a[0]],len(lens))
# zip those two info for final o/p
return zip(grpID,lens)
样本运行-
In [221]: a
Out[221]: [True, True, False, True, True, True, False]
In [222]: keep_longest_true(a)
Out[222]: array([False, False, False, True, True, True, False])
In [223]: island_info(keep_longest_true(a))
Out[223]: [(False, 3), (True, 3), (False, 1)]
我正在尝试 return 一个只给出原始布尔值中最长 "True" 出现的布尔值,并将较短的 "True" 块替换为 "False"。示例 a=[True, True, False, True , True, True, False],我想 return [False, False, False, True, True, True, False].
我试过 more_itertools 它似乎有一些有趣的功能,但不确定如何准确地实现我的目的。
a=[True, True, False, True , True, True, False]
pred = lambda x: x in {True}
p=list(mit.run_length.encode(a))
>>>
Results in: (True,2),(False,1),(True,3),(False,1)
所以我想最终自动得到的是(False,3),(True,3),(False,1)。有什么建议么? 感谢您的帮助
以下解决方案在使用 more_itertools.run_length 后应该有效。
本质上,逻辑是找到True的最长子序列的长度,以及该索引在result
列表中的位置
然后计算最长子序列前后的元素总数,然后相应地构造结果元组列表。
import more_itertools as mit
a=[True, True, False, True , True, True, False]
result = list(mit.run_length.encode(a))
#Find the length of longest subsequence of True, and the location if that index in result
max_true_count = -1
max_true_idx = -1
for idx, (val, count) in enumerate(result):
if val and max_true_count < count:
max_true_count = count
max_true_idx = idx
#Find total elements before and after the longest subsequence tuple
elems_before_idx = sum((idx[1] for idx in result[:max_true_idx]))
elems_after_idx = sum((idx[1] for idx in result[max_true_idx+1:]))
#Create the output list using the information
output = [(False, elems_before_idx), (True, max_true_count), (False, elems_after_idx)]
print(output)
输出将是
[(False, 3), (True, 3), (False, 1)]
这是一个矢量化的 -
def keep_longest_true(a):
# Convert to array
a = np.asarray(a)
# Attach sentients on either sides w.r.t True
b = np.r_[False,a,False]
# Get indices of group shifts
s = np.flatnonzero(b[:-1]!=b[1:])
# Get group lengths and hence the max index group
m = (s[1::2]-s[::2]).argmax()
# Initialize array and assign only the largest True island as True.
out = np.zeros_like(a)
out[s[2*m]:s[2*m+1]] = 1
return out
def island_info(a):
'''' Get island tuple info
'''
# Attach sentients on either sides w.r.t array start and end
b = np.r_[~a[0],a,~a[-1]]
# Get group lengths and group start elements
lens = np.diff(np.flatnonzero(b[:-1] != b[1:]))
grpID = np.resize([a[0],~a[0]],len(lens))
# zip those two info for final o/p
return zip(grpID,lens)
样本运行-
In [221]: a
Out[221]: [True, True, False, True, True, True, False]
In [222]: keep_longest_true(a)
Out[222]: array([False, False, False, True, True, True, False])
In [223]: island_info(keep_longest_true(a))
Out[223]: [(False, 3), (True, 3), (False, 1)]