【问题标题】:Skipping the sliding window跳过滑动窗口
【发布时间】:2017-09-23 09:41:25
【问题描述】:

给定[1,2,3,4,5,6,7,8,9,10],一次获取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)]

来自https://stackoverflow.com/q/42220614/610569,可以通过以下方式实现序列的滑动窗口:

def per_window(sequence, n=1):
    """
    Returns a sliding window.
    From https://stackoverflow.com/q/42220614/610569
        >>> 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

但是,如果我想在滑动窗口中设置一些约束,并且我只想获取存在某个元素的窗口。

假设我只想要包含 4 个的窗口,我可以这样:

>>> [window for window in per_window(x, 3) if 4 in window]
[((2, 3, 4), (3, 4, 5), (4,5,6)]

但不知何故,循环仍然必须处理整个窗口列表并检查 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 https://stackoverflow.com/q/43626525/610569
    """
    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)]

【问题讨论】:

    标签: python constraints sequence sliding-window


    【解决方案1】:

    除了在 per_window 函数之外查找索引,还有其他方法可以在 per_window 函数中添加这样的约束吗?

    是的,您可以在 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
    

    【讨论】:

    • 但这仍然会遍历每个可能的窗口,只是如果它没有通过约束它就不会产生,不是吗? =(
    • 给出的答案与提出的问题相符。此外,很明显,您已经知道通过使用 index() 快速前进到下一个可能的匹配子序列的进一步优化的路径。
    • 谢谢@RaymondHettinger!只需确认不包括“快进”优化。我在想我是否错过了什么=)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-05
    • 2012-08-08
    • 2012-10-20
    • 1970-01-01
    • 2020-08-08
    • 1970-01-01
    相关资源
    最近更新 更多