我需要从已经给定的列表中创建一个大小为N的列表。
N = 3
a_list = [10,4,18,2,6,19,24,1,20]
O / P应该是:
[10,4,18] [4,18,2] [18,2,6] [2,6,19] [6,19,24] [19,24,1] [24,1,20]
它就像一个N = 3的窗口大小,向右滑动一步。
我将如何做?
答案 0 :(得分:5)
使用列表理解和切片:
>>> lis = [10,4,18,2,6,19,24,1,20]
>>> n = 3
>>> [lis[i:i+n] for i in xrange(len(lis)-n+1)]
[[10, 4, 18], [4, 18, 2], [18, 2, 6], [2, 6, 19], [6, 19, 24], [19, 24, 1], [24, 1, 20]]
>>> n = 4
>>> [lis[i:i+n] for i in xrange(len(lis)-n+1)]
[[10, 4, 18, 2], [4, 18, 2, 6], [18, 2, 6, 19], [2, 6, 19, 24], [6, 19, 24, 1], [19, 24, 1, 20]]
对于更大的列表,基于zip
的方法实际上更慢:
In [27]: n = 100
In [28]: lis = [10,4,18,2,6,19,24,1,20]*10000
In [30]: %timeit zip(*[lis[i:] for i in xrange(n)])
1 loops, best of 3: 593 ms per loop
In [31]: %timeit [lis[i:i+n] for i in xrange(len(lis)-n+1)]
10 loops, best of 3: 114 ms per loop
答案 1 :(得分:5)
更快捷的方式:
>>> zip(a_list,a_list[1:],a_list[2:])
[(10, 4, 18), (4, 18, 2), (18, 2, 6), (2, 6, 19), (6, 19, 24), (19, 24, 1), (24, 1, 20)]
比较:
In [6]: %timeit [a_list[i:i+n] for i in xrange(len(a_list)-n+1)]
100000 loops, best of 3: 9.61 us per loop
In [7]: %timeit zip(a_list,a_list[1:],a_list[2:])
100000 loops, best of 3: 5.23 us per loop
或者更一般:
>>> zip(*[a_list[i:] for i in range(3)]) #3 (or 2, 4, 5, etc)is the length of step
对于较大的list
,可能必须使用numpy
来获得比@Ashwini Chaudhary(http://www.rigtorp.se/2011/01/01/rolling-statistics-numpy.html)更快的解决方案:
import numpy as np
lista=np.array(lis)
def rolling_window(a, window):
shape = a.shape[:-1] + (a.shape[-1] - window + 1, window)
strides = a.strides + (a.strides[-1],)
return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)
%timeit [lis[i:i+n] for i in xrange(len(lis)-n+1)]
%timeit rolling_window(lista, n)
1 loops, best of 3: 171 ms per loop
100000 loops, best of 3: 19.7 µs per loop
答案 2 :(得分:0)
试试这个
>>> lis = [10,4,18,2,6,19,24,1,20]
>>> n=3
>>> [lis[i:i+n] for i in range(len(lis))][:-2]
输出
[[10, 4, 18], [4, 18, 2], [18, 2, 6], [2, 6, 19], [6, 19, 24], [19, 24, 1], [24, 1, 20]]