如何在两个方向(向前,向后)获取每个元素的值的滑动窗口?

use*_*_12 29 python python-3.x

我有一个这样的值列表,

lst = [1, 2, 3, 4, 5, 6, 7, 8]
Run Code Online (Sandbox Code Playgroud)

期望输出

window size = 3
    1  # first element in the list
    forward = [2, 3, 4]
    backward = []

    2  # second element in the list
    forward = [3, 4, 5]
    backward = [1]

    3  # third element in the list
    forward = [4, 5, 6]
    backward = [1, 2]

    4  # fourth element in the list
    forward = [5, 6, 7]
    backward = [1, 2, 3]

    5  # fifth element in the list
    forward = [6, 7, 8]
    backward = [2, 3, 4]

    6  # sixth element in the list
    forward = [7, 8]
    backward = [3, 4, 5]

    7  # seventh element in the list
    forward = [8]
    backward = [4, 5, 6]

    8  # eight element in the list
    forward = []
    backward = [5, 6, 7]
Run Code Online (Sandbox Code Playgroud)

让我们假设窗口大小为 4,现在我想要的输出:

对于列表中的 each_element,我想要前面的 4 个值和后面的 4 个值,忽略当前值。

我能够使用它来获取值的滑动窗口,但这也没有给我正确的所需输出。

import more_itertools
list(more_itertools.windowed([1, 2, 3, 4, 5, 6, 7, 8], n=3))
Run Code Online (Sandbox Code Playgroud)

Anu*_*agh 15

代码:

arr = [1, 2, 3, 4, 5, 6, 7, 8]
window = 3
for backward, current in enumerate(range(len(arr)), start = 0-window):
    if backward < 0:
        backward = 0
    print(arr[current+1:current+1+window], arr[backward:current])
Run Code Online (Sandbox Code Playgroud)

输出:

[2, 3, 4], []
[3, 4, 5], [1]
[4, 5, 6], [1, 2]
[5, 6, 7], [1, 2, 3]
[6, 7, 8], [2, 3, 4]
[7, 8], [3, 4, 5]
[8], [4, 5, 6]
[], [5, 6, 7]
Run Code Online (Sandbox Code Playgroud)

一个班轮:

print(dict([(e, (lst[i+1:i+4], lst[max(i-3,0):i])) for i,e in enumerate(last)]))
Run Code Online (Sandbox Code Playgroud)

输出:

{1: ([2, 3, 4], []),
 2: ([3, 4, 5], [1]),
 3: ([4, 5, 6], [1, 2]),
 4: ([5, 6, 7], [1, 2, 3]),
 5: ([6, 7, 8], [2, 3, 4]),
 6: ([7, 8], [3, 4, 5]),
 7: ([8], [4, 5, 6]),
 8: ([], [5, 6, 7])}
Run Code Online (Sandbox Code Playgroud)

信用:感谢@FeRD 和@Androbin 的建议,解决方案现在看起来更好

  • @AnuragWagh 尝试最大(向后,0) (3认同)

Hub*_*iak 12

这应该让你开始:

from dataclasses import dataclass
from typing import List

@dataclass
class Window:
  index: int
  backward: List[int]
  forward: List[int]

def window(iterable, window_size, index):
  backward = iterable[max(0, index - window_size):index]
  forward = iterable[index + 1:index + 1 + window_size]
  return Window(index, backward, forward)
Run Code Online (Sandbox Code Playgroud)
>>> window([1,2,3,4,5,6], 3, 0)
Window(index=0, backward=[], forward=[2, 3, 4])
>>> window([1,2,3,4,5,6], 3, 5)
Window(index=5, backward=[3, 4, 5], forward=[])
Run Code Online (Sandbox Code Playgroud)

我还建议添加一些检查索引和窗口大小是否有意义。

如果您坚持使用还没有数据类的旧 Python 版本,您可以改用命名元组


bba*_*les 8

more_itertools.windowed如果您调整窗口大小,这将起作用。由于您需要 7 个项目(3 个向后,1 个当前,3 个向前),将窗口大小设置为 7。

from itertools import chain
from more_itertools import windowed
n = 3
iterable = [1, 2, 3, 4, 5, 6, 7, 8]
# pad the iterable so you start with an empty backward window
it = chain([None] * n, iterable, [None] * n)

for window in windowed(it, n * 2 + 1):
    print(window[n])
    print('forward =', [x for x in window[n + 1:] if x is not None])
    print('backward =', [x for x in window[:n] if x is not None])
Run Code Online (Sandbox Code Playgroud)

输出是:

1
forward = [2, 3, 4]
backward = []

2
forward = [3, 4, 5]
backward = [1]

3
forward = [4, 5, 6]
backward = [1, 2]

4
forward = [5, 6, 7]
backward = [1, 2, 3]

5
forward = [6, 7, 8]
backward = [2, 3, 4]

6
forward = [7, 8]
backward = [3, 4, 5]

7
forward = [8]
backward = [4, 5, 6]

8
forward = []
backward = [5, 6, 7]
Run Code Online (Sandbox Code Playgroud)