Python 找到1'的最长序列的起始位置;s
我想找到数组中最长的1序列的起始位置:Python 找到1'的最长序列的起始位置;s,python,numpy,scipy,Python,Numpy,Scipy,我想找到数组中最长的1序列的起始位置: a1=[0,0,1,1,1,1,0,0,1,1] #2 下面我将查找最长序列的长度。但是,我无法确定位置。您可以使用for循环并检查接下来的几个项目(长度m,其中m是最大长度)是否与最大长度相同: # Using your list and the answer from the post you referred from itertools import groupby L = [0,0,1,1,1,1,0,0,1,1] m = max(sum(1
a1=[0,0,1,1,1,1,0,0,1,1]
#2
下面我将查找最长序列的长度。但是,我无法确定位置。您可以使用for循环并检查接下来的几个项目(长度
m
,其中m
是最大长度)是否与最大长度相同:
# Using your list and the answer from the post you referred
from itertools import groupby
L = [0,0,1,1,1,1,0,0,1,1]
m = max(sum(1 for i in g) for k, g in groupby(L))
# Here is the for loop
for i, s in enumerate(L):
if len(L) - i + 2 < len(L) - m:
break
if s == 1 and 0 not in L[i:i+m]:
print i
break
受此启发,这里有一个矢量化方法来解决它-
# Get start, stop index pairs for islands/seq. of 1s
idx_pairs = np.where(np.diff(np.hstack(([False],a1==1,[False]))))[0].reshape(-1,2)
# Get the island lengths, whose argmax would give us the ID of longest island.
# Start index of that island would be the desired output
start_longest_seq = idx_pairs[np.diff(idx_pairs,axis=1).argmax(),0]
样本运行-
In [89]: a1 # Input array
Out[89]: array([0, 0, 1, 1, 1, 1, 0, 0, 1, 1])
In [90]: idx_pairs # Start, stop+1 index pairs
Out[90]:
array([[ 2, 6],
[ 8, 10]])
In [91]: np.diff(idx_pairs,axis=1) # Island lengths
Out[91]:
array([[4],
[2]])
In [92]: np.diff(idx_pairs,axis=1).argmax() # Longest island ID
Out[92]: 0
In [93]: idx_pairs[np.diff(idx_pairs,axis=1).argmax(),0] # Longest island start
Out[93]: 2
这似乎是可行的,使用
itertools
中的groupby
,这只会遍历列表一次:
from itertools import groupby
pos, max_len, cum_pos = 0, 0, 0
for k, g in groupby(a1):
if k == 1:
pat_size = len(list(g))
pos, max_len = (pos, max_len) if pat_size < max_len else (cum_pos, pat_size)
cum_pos += pat_size
else:
cum_pos += len(list(g))
pos
# 2
max_len
# 4
从itertools导入groupby
pos,max_len,cum_pos=0,0,0
对于groupby(a1)中的k,g:
如果k==1:
pat_size=len(列表(g))
位置,最大长度=(位置,最大长度)如果零件尺寸<最大长度,则为其他零件(共位置,零件尺寸)
cum_pos+=零件尺寸
其他:
cum_pos+=len(列表(g))
销售时点情报系统
# 2
麦克斯伦
# 4
在单个循环中执行操作的另一种方法,但不必求助于itertool
的groupby
max_start = 0
max_reps = 0
start = 0
reps = 0
for (pos, val) in enumerate(a1):
start = pos if reps == 0 else start
reps = reps + 1 if val == 1 else 0
max_reps = max(reps, max_reps)
max_start = start if reps == max_reps else max_start
这也可以通过使用reduce
以单行方式完成:
max_start = reduce(lambda (max_start, max_reps, start, reps), (pos, val): (start if reps == max(reps, max_reps) else max_start, max(reps, max_reps), pos if reps == 0 else start, reps + 1 if val == 1 else 0), enumerate(a1), (0, 0, 0, 0))[0]
在Python 3中,无法在lambda
参数定义中解包元组,因此最好先使用def
定义函数:
def func(acc, x):
max_start, max_reps, start, reps = acc
pos, val = x
return (start if reps == max(reps, max_reps) else max_start,
max(reps, max_reps),
pos if reps == 0 else start,
reps + 1 if val == 1 else 0)
max_start = reduce(func, enumerate(a1), (0, 0, 0, 0))[0]
在这三种情况中的任何一种情况下,
max\u start
给出您的答案(即2
)。使用groupby()
的更紧凑的单行程序。在原始数据上使用enumerate()
,通过分析管道保留起始位置,最终以元组列表[(2,4)、(8,2)]结束,每个元组包含非零运行的起始位置和长度:
from itertools import groupby
L = [0,0,1,1,1,1,0,0,1,1]
print max(((lambda y: (y[0][0], len(y)))(list(g)) for k, g in groupby(enumerate(L), lambda x: x[1]) if k), key=lambda z: z[1])[0]
lambda:x
是groupby()的关键函数
lambda:y
打包我们需要的结果,因为我们只能评估g
一次,而不保存
lambda:z
是max()
拉出长度的关键函数
按预期打印“2”。使用第三方库:
给定的
import itertools as it
import more_itertools as mit
lst = [0, 0, 1, 1, 1, 1, 0, 0, 1, 1]
代码
longest_contiguous = max([tuple(g) for _, g in it.groupby(lst)], key=len)
longest_contiguous
# (1, 1, 1, 1)
pred = lambda w: w == longest_contiguous
next(mit.locate(mit.windowed(lst, len(longest_contiguous)), pred=pred))
# 2
有关这些工具如何工作的详细信息,请参见docstring。漂亮的解决方案!
longest_contiguous = max([tuple(g) for _, g in it.groupby(lst)], key=len)
longest_contiguous
# (1, 1, 1, 1)
pred = lambda w: w == longest_contiguous
next(mit.locate(mit.windowed(lst, len(longest_contiguous)), pred=pred))
# 2