Скользящее окно шириной n над заданным итерируемым - PullRequest
2 голосов
/ 09 апреля 2019

У меня есть последовательность, размер окна и шаг:

seq = [0,1,2,3,4]
n=4
step=2

from more_itertools import windowed
list(windowed([0,1,2,3,4], n, fillvalue=0, step=step))

результат:

[(0, 1, 2, 3), (2, 3, 4, 0)]

но мне нужно:

[(0, 1, 2, 3), (2, 3, 4, 0), (4, 0, 0, 0)]

Пожалуйста, помогите мне найти решение

Ответы [ 4 ]

3 голосов
/ 09 апреля 2019

это также должно работать с итерациями, а не только с последовательностями:

from itertools import islice

def sliding_window(seq, n, step, fillvalue=None):
    it = iter(seq)
    values = tuple(islice(it, n))
    while values:
        yield values + (n-len(values)) * (fillvalue, )
        values = values[step:] + tuple(islice(it, step))

функция выводит:

print(list(sliding_window(seq, n, step, fillvalue=0)))
# [(0, 1, 2, 3), (2, 3, 4, 0), (4, 0, 0, 0)]

большая часть его заимствована из оригинального рецепта itertools для скользящего окна .

3 голосов
/ 09 апреля 2019

Просто напишите свою собственную windowed функцию:

def windowed(iterable, size, fillvalue=None, step=1):
    for i in range(0, len(iterable), step):
        window = iterable[i:i+size]
        window += [fillvalue] * (size - len(window))
        yield window
>>> list(windowed([0,1,2,3,4], 4, fillvalue=0, step=2))
[[0, 1, 2, 3], [2, 3, 4, 0], [4, 0, 0, 0]]
2 голосов
/ 09 апреля 2019

Как насчет использования padded ?

seq = [0,1,2,3,4]
n=4
step=2

from more_itertools import windowed, padded
list(windowed(padded(seq, 0, n=n, next_multiple=True), n, step=step))
0 голосов
/ 13 апреля 2019

Рассмотрим more_itertools.stagger:

С учетом

import itertools as it

import more_itertools as mit


iterable = [0, 1, 2, 3, 5]

код

Получить все результаты от раздвижных окон:

windows = list(mit.stagger(iterable, offsets=(0, 1, 2, 3), longest=True, fillvalue=0))
windows
# [(0, 1, 2, 3), (1, 2, 3, 5), (2, 3, 5, 0), (3, 5, 0, 0), (5, 0, 0, 0)]

Далее отфильтруйте желаемые результаты:

[w for i, w in enumerate(windows) if not (i % 2)]
# [(0, 1, 2, 3), (2, 3, 5, 0), (5, 0, 0, 0)]

или срез итерация:

list(it.islice(windows, 0, None, 2))
# [(0, 1, 2, 3), (2, 3, 5, 0), (5, 0, 0, 0)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...