在 python for 循环中实现移动 window 的最佳方法?

Best way to implement moving window in python for loop?

我有一个可以迭代的单词(标记)列表。我想在移动该列表的 windows 时执行某种转换。 windows大小可以变长

for i in range(0,len(tokens)-(window_size+1),step):
    doc2vec.model.infer_vector(tokens[i:i+window_size])

for 循环按照变量中定义的步骤遍历标记的长度,它需要与变量 window_size 所说的一样多的标记。我看到的问题是在上一次迭代中。迭代以标记的长度结束 - windows 大小(+1 以便包括减去的值)。假设 window 大小为 10,步长为 5,令牌长度为 98。在这种情况下,我的代码将在 85:95 处进行最后一次计算并省略最后三个元素。我想要一个适用于变量 window_size、步长和标记长度的解决方案。举个例子,到目前为止,如果标记的长度是 95,它就可以正常工作,但如果是 98,就会剩下三个元素。我希望它们一起计算 88:98.

我认为要走的路是创建您自己的自定义迭代器:

class MovingWindow:
    def __init__(self, tokens, window_size, step):
        self.current = -step
        self.last = len(tokens) - window_size + 1
        self.remaining = (len(tokens) - window_size) % step
        self.tokens = tokens
        self.window_size = window_size
        self.step = step

    def __iter__(self):
        return self

    def __next__(self):
        self.current += self.step
        if self.current < self.last:
            return self.tokens[self.current : self.current + self.window_size]
        elif self.remaining:
            self.remaining = 0
            return self.tokens[-self.window_size:]
        else:
            raise StopIteration

您将通过以下方式访问:

for t in MovingWindow(tokens, 10, 5):
    doc2vec.model.infer_vector(t)

您还可以修改迭代器,使其 return 成为索引而不是标记。 另一种选择是创建一个简单的生成器,更多信息 here

为了说明您提供的案例:

indexes = [i for i in range(98)]
for i in MovingWindow(indexes, 10, 5):
    print(f'{i[0]}:{i[-1]}')

输出:

0:9
5:14
10:19
15:24
20:29
25:34
30:39
35:44
40:49
45:54
50:59
55:64
60:69
65:74
70:79
75:84
80:89
85:94
88:97