如何处理不是分组大小倍数的序列上的滑动 window 值?
How to handle a sliding window of values over sequences that aren't multiples of the grouping size?
我有一个列表,我想使用滑动 window 方法将我的列表分组为三个元素的元组。
根据我的循环中设置的参数,一旦 i
到达最后两个元素,三元组将被截断,因为列表末尾没有更多值。
我需要的是在达到该点后使用起始值。请查看屏幕截图,因为它可能会更好地显示我的问题。
test = [(1,2), (3,4), (5,6), (7,8)]
for i in range(len(test)):
print(test[i : i+3])
输出为:
[(1, 2), (3, 4), (5, 6)]
[(3, 4), (5, 6), (7, 8)]
[(5, 6), (7, 8)]
[(7, 8)]
但是,我需要它来做:
[(1, 2), (3, 4), (5, 6)]
[(3, 4), (5, 6), (7, 8)]
[(5, 6), (7, 8), (1, 2)]
[(7, 8), (1, 2), (2, 3)]
然后将其展平使其最终看起来像:
[((1, 2), (3, 4), (5, 6))
((3, 4), (5, 6), (7, 8))
((5, 6), (7, 8), (1, 2))
((7, 8), (1, 2), (2, 3))]
Screenshot of output for better clarity
有什么方法可以做到这一点?
可能有优化以下内容的方法,但一种方法是使用 operator.itemgetter()
并为每个 window 子组创建适当的索引集。
from operator import itemgetter
from pprint import pprint
test = [(1,2), (3,4), (5,6), (7,8)]
window_size = 3
length = len(test)
result = []
for i in range(len(test)):
indices = (x%length for x in range(i, i+window_size))
result.append(itemgetter(*indices)(test))
pprint(result)
输出:
[((1, 2), (3, 4), (5, 6)),
((3, 4), (5, 6), (7, 8)),
((5, 6), (7, 8), (1, 2)),
((7, 8), (1, 2), (3, 4))]
接受的答案很好,但我会提供(我认为是)更简单的方法:
test = [(1,2), (3,4), (5,6), (7,8)]
win_size = 3
groups = []
for i in range(len(test)):
groups.append((test[i:] + test[:i])[:win_size])
print(groups)
输出:
[[(1, 2), (3, 4), (5, 6)],
[(3, 4), (5, 6), (7, 8)],
[(5, 6), (7, 8), (1, 2)],
[(7, 8), (1, 2), (3, 4)]]
每次通过循环,我们都会重新排列 test
以使其处于所需的顺序,然后通过按 window 大小切片来创建每个组。
尽管我认为它的可读性较差,但您也可以使用列表推导式:
groups = [(test[i:] + test[:i])[:win_size] for i in range(len(test))]
如果组必须是元组而不是列表,请最初将 test
定义为元组,或酌情使用 tuple(test[i:] + test[:i])
。
我有一个列表,我想使用滑动 window 方法将我的列表分组为三个元素的元组。
根据我的循环中设置的参数,一旦 i
到达最后两个元素,三元组将被截断,因为列表末尾没有更多值。
我需要的是在达到该点后使用起始值。请查看屏幕截图,因为它可能会更好地显示我的问题。
test = [(1,2), (3,4), (5,6), (7,8)]
for i in range(len(test)):
print(test[i : i+3])
输出为:
[(1, 2), (3, 4), (5, 6)]
[(3, 4), (5, 6), (7, 8)]
[(5, 6), (7, 8)]
[(7, 8)]
但是,我需要它来做:
[(1, 2), (3, 4), (5, 6)]
[(3, 4), (5, 6), (7, 8)]
[(5, 6), (7, 8), (1, 2)]
[(7, 8), (1, 2), (2, 3)]
然后将其展平使其最终看起来像:
[((1, 2), (3, 4), (5, 6))
((3, 4), (5, 6), (7, 8))
((5, 6), (7, 8), (1, 2))
((7, 8), (1, 2), (2, 3))]
Screenshot of output for better clarity
有什么方法可以做到这一点?
可能有优化以下内容的方法,但一种方法是使用 operator.itemgetter()
并为每个 window 子组创建适当的索引集。
from operator import itemgetter
from pprint import pprint
test = [(1,2), (3,4), (5,6), (7,8)]
window_size = 3
length = len(test)
result = []
for i in range(len(test)):
indices = (x%length for x in range(i, i+window_size))
result.append(itemgetter(*indices)(test))
pprint(result)
输出:
[((1, 2), (3, 4), (5, 6)),
((3, 4), (5, 6), (7, 8)),
((5, 6), (7, 8), (1, 2)),
((7, 8), (1, 2), (3, 4))]
接受的答案很好,但我会提供(我认为是)更简单的方法:
test = [(1,2), (3,4), (5,6), (7,8)]
win_size = 3
groups = []
for i in range(len(test)):
groups.append((test[i:] + test[:i])[:win_size])
print(groups)
输出:
[[(1, 2), (3, 4), (5, 6)],
[(3, 4), (5, 6), (7, 8)],
[(5, 6), (7, 8), (1, 2)],
[(7, 8), (1, 2), (3, 4)]]
每次通过循环,我们都会重新排列 test
以使其处于所需的顺序,然后通过按 window 大小切片来创建每个组。
尽管我认为它的可读性较差,但您也可以使用列表推导式:
groups = [(test[i:] + test[:i])[:win_size] for i in range(len(test))]
如果组必须是元组而不是列表,请最初将 test
定义为元组,或酌情使用 tuple(test[i:] + test[:i])
。