跳过滑动 window
Skipping the sliding window
给定 [1,2,3,4,5,6,7,8,9,10]
,一次滑动 window 3 个项目得到:
[(1, 2, 3), (2, 3, 4), (3, 4, 5), (4, 5, 6), (5, 6, 7), (6, 7, 8), (7, 8, 9), (8, 9, 10)]
从开始,可以通过以下方式实现序列的滑动window:
def per_window(sequence, n=1):
"""
Returns a sliding window.
From
>>> list(per_window([1,2,3,4], n=2))
[(1, 2), (2, 3), (3, 4)]
>>> list(per_window([1,2,3,4], n=3))
[(1, 2, 3), (2, 3, 4)]
"""
start, stop = 0, n
seq = list(sequence)
while stop <= len(seq):
yield tuple(seq[start:stop])
start += 1
stop += 1
但是如果我想在滑动 window 中添加一些约束,并且我只想获取存在某个元素的 windows。
假设我只想要包含 4 的 windows,我可以这样:
>>> [window for window in per_window(x, 3) if 4 in window]
[((2, 3, 4), (3, 4, 5), (4,5,6)]
但不知何故,循环仍然必须处理整个 windows 列表并检查 if 条件。
我可以通过查找 4
的位置来进行一些跳过,并将输入限制在 per_window
,例如
# Input sequence.
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Window size.
n = 3
# Constraint.
c = 4
# Set the index to 0
i = 0
while i < len(x)-n:
i = x.index(4, i)
# First window where the constraint is met.
left = i - (n-1)
if left > 0:
print (list(per_window(x[left:i], 3)))
right = i + n
if right < len(x):
print (list(per_window(x[i:right], 3)))
i = right
(请注意上面带有 ifs 的代码不起作用 =( )
除了在 per_window
函数之外查找索引,还有另一种方法可以在 per_window
函数中添加这样的约束吗?
已编辑
看完@RaymondHettinger 的回答后:
def skipping_window(sequence, target, n=3):
"""
Return a sliding window with a constraint to check that
target is inside the window.
From
"""
start, stop = 0, n
seq = list(sequence)
while stop <= len(seq):
subseq = seq[start:stop]
if target in subseq:
yield tuple(seq[start:stop])
start += 1
stop += 1
# Fast forwarding the start.
# Find the next window which contains the target.
try:
# `seq.index(target, start) - (n-1)` would be the next
# window where the constraint is met.
start = max(seq.index(target, start) - (n-1), start)
stop = start + n
except ValueError:
break
[输出]:
>>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> list(skipping_window(x, 4, 3))
[(2, 3, 4), (3, 4, 5), (4, 5, 6)]
Instead of finding the index outside of the per_window function, is there another way to add such a constraint in the per_window function?
是的,您可以在 yield 之前添加条件:
def per_window(sequence, target, n=1):
start, stop = 0, n
seq = list(sequence)
while stop <= len(seq):
subseq = seq[start:stop]
if target in subseq:
yield tuple(subseq)
start += 1
stop += 1
给定 [1,2,3,4,5,6,7,8,9,10]
,一次滑动 window 3 个项目得到:
[(1, 2, 3), (2, 3, 4), (3, 4, 5), (4, 5, 6), (5, 6, 7), (6, 7, 8), (7, 8, 9), (8, 9, 10)]
从开始,可以通过以下方式实现序列的滑动window:
def per_window(sequence, n=1):
"""
Returns a sliding window.
From
>>> list(per_window([1,2,3,4], n=2))
[(1, 2), (2, 3), (3, 4)]
>>> list(per_window([1,2,3,4], n=3))
[(1, 2, 3), (2, 3, 4)]
"""
start, stop = 0, n
seq = list(sequence)
while stop <= len(seq):
yield tuple(seq[start:stop])
start += 1
stop += 1
但是如果我想在滑动 window 中添加一些约束,并且我只想获取存在某个元素的 windows。
假设我只想要包含 4 的 windows,我可以这样:
>>> [window for window in per_window(x, 3) if 4 in window]
[((2, 3, 4), (3, 4, 5), (4,5,6)]
但不知何故,循环仍然必须处理整个 windows 列表并检查 if 条件。
我可以通过查找 4
的位置来进行一些跳过,并将输入限制在 per_window
,例如
# Input sequence.
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Window size.
n = 3
# Constraint.
c = 4
# Set the index to 0
i = 0
while i < len(x)-n:
i = x.index(4, i)
# First window where the constraint is met.
left = i - (n-1)
if left > 0:
print (list(per_window(x[left:i], 3)))
right = i + n
if right < len(x):
print (list(per_window(x[i:right], 3)))
i = right
(请注意上面带有 ifs 的代码不起作用 =( )
除了在 per_window
函数之外查找索引,还有另一种方法可以在 per_window
函数中添加这样的约束吗?
已编辑
看完@RaymondHettinger 的回答后:
def skipping_window(sequence, target, n=3):
"""
Return a sliding window with a constraint to check that
target is inside the window.
From
"""
start, stop = 0, n
seq = list(sequence)
while stop <= len(seq):
subseq = seq[start:stop]
if target in subseq:
yield tuple(seq[start:stop])
start += 1
stop += 1
# Fast forwarding the start.
# Find the next window which contains the target.
try:
# `seq.index(target, start) - (n-1)` would be the next
# window where the constraint is met.
start = max(seq.index(target, start) - (n-1), start)
stop = start + n
except ValueError:
break
[输出]:
>>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> list(skipping_window(x, 4, 3))
[(2, 3, 4), (3, 4, 5), (4, 5, 6)]
Instead of finding the index outside of the per_window function, is there another way to add such a constraint in the per_window function?
是的,您可以在 yield 之前添加条件:
def per_window(sequence, target, n=1):
start, stop = 0, n
seq = list(sequence)
while stop <= len(seq):
subseq = seq[start:stop]
if target in subseq:
yield tuple(subseq)
start += 1
stop += 1