迭代列表的 n 个连续元素(重叠)
问题描述
itertools python 模块为迭代器实现了一些基本构建块.正如他们所说,它们形成了一个迭代器代数".我期待,但我找不到使用该模块进行以下迭代的简洁方法.给定一个有序实数列表,例如
The itertools python module implements some basic building blocks for iterators. As they say, "they form an iterator algebra". I was expecting, but I could not find a succinctly way of doing the following iteration using the module. Given a list of ordered real numbers, for example
a = [1.0,1.5,2.0,2.5,3.0]
...返回一个新列表(或只是迭代)按一些 n
值分组,比如 2
... return a new list (or just iterate) grouping by some n
value, say 2
b = [(1.0,1.5),(1.5,2.0),(2.0,2.5),(2.5,3.0)]
我发现这样做的方法如下.首先将列表一分为二,带有偶数和赔率索引:
The way I found of doing this was as follows. First split the list in two, with evens and odds indexes:
even, odds = a[::2], a[1::2]
然后构造新列表:
b = [(even, odd) for even, odd in zip(evens, odds)]
b = sorted(b + [(odd, even) for even, odd in zip(evens[1:], odds)])
本质上,它类似于移动均值.
In essence, it is similar to a moving mean.
是否有简洁的方法(使用或不使用 itertools)?
PS:
应用程序
将 a
列表想象为实验期间发生的某些事件的时间戳集:
Imagine the a
list as the set of timestamps of some events occurred during an experiment:
timestamp event
47.8 1a
60.5 1b
67.4 2a
74.5 2b
78.5 1a
82.2 1b
89.5 2a
95.3 2b
101.7 1a
110.2 1b
121.9 2a
127.1 2b
...
此代码用于根据不同的时间窗口对这些事件进行分段.现在我对 2
连续事件之间的数据感兴趣;'n > 2' 仅用于探索目的.
This code is being used to segment those events in accord with different temporal windows. Right now I am interested in the data between 2
successive events; 'n > 2' would be used only for exploratory purposes.
解决方案
对于2,你可以这样做
b = zip(a, a[1:]) # or list(zip(...)) on Python 3 if you really want a list
对于固定的 n,技术类似:
For fixed n, the technique is similar:
# n = 4
b = zip(a, a[1:], a[2:], a[3:])
对于变量 n,您可以压缩可变数量的切片,或者(尤其是当窗口大小接近 a
的大小时)您可以使用切片直接获取窗口:
For variable n, you could zip a variable number of slices, or (especially if the window size is close to the size of a
) you could use slicing to take windows directly:
b = zip(*[a[i:] for i in xrange(n)])
# or
b = [tuple(a[i:i+n]) for i in xrange(len(a)-n+1)]
如果 a
不是列表,您可以从 itertools 文档中概括 pairwise
配方:
If a
is not a list, you could generalize the pairwise
recipe from the itertools docs:
import copy
import itertools
def nwise(iterable, n):
# Make n tees at successive positions along the iterable.
tees = list(itertools.tee(iterable, 1))
for _ in xrange(n-1):
tees.append(copy.copy(tees[-1]))
next(tees[-1])
return zip(*tees)
相关文章