2011-02-08 50 views
6

标题编辑:大写固定,并添加'for python'。在Python中对一个系列进行分组

有没有更好或更标准的方法来做我所描述的? 我想输入这样的:

[1, 1, 1, 0, 2, 2, 0, 2, 2, 0, 0, 3, 3, 0, 1, 1, 1, 1, 1, 2, 2, 2]

进行改造,以这样的:

[0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0]

,或者甚至更好,这样的事情(描述不同类似的输出,但现在不仅限于整数):

标签:[1, 2, 3, 1, 2]

职位(其中1确定了第一个可占位置,按照我的matplotlib图):[2, 7, 12.5, 17, 21]

输入数据是分类图的分类数据 - 在下图中,分组图表共享我希望的分类特征只为该组标记一次。我将使用2个轴来表示两个不同的变量,但我认为那不是现在的要点。

注意:此图像不反映任何一组样本数据 - 只是想要将类别分组在一起。由于前两个数据组和第二个垂直数据组之间存在空白区,因此组a应该标记为x = 5,而0是右侧的行。

Image demonstrating placement of tick marks in the center of a category of data

下面是我得到了什么:

data = [1, 1, 1, 2, 2, 2, 2, 2, 3, 4, 3, 2, 2, 1, 1, 1, 1] 
last = None 
runs = [] 
labels = [] 
run = 1 
for x in data: 
    if x in (last, 0): 
     run += 1 
    else: 
     runs.append(run) 
     run = 1 
     labels.append(x) 
    last = x 
runs.append(run) 
runs.pop(0) 
labels.append(x) 
tick_positions = [0] 
last_run = 1 
for run in runs: 
    tick_positions.append(run/2.0+last_run/2.0+tick_positions[-1]) 
    last_run = run 
tick_positions.pop(0) 
print tick_positions 

回答

8

为了让标签可以使用itertools groupby

>>> import itertools 
>>> numbers = [1, 1, 1, 0, 2, 2, 0, 2, 2, 0, 0, 3, 3, 0, 1, 1, 1, 1, 1, 2, 2, 2] 
>>> list(k for k, g in itertools.groupby(numbers)) 
[1, 0, 2, 0, 2, 0, 3, 0, 1, 2] 

,并消除了零,您可以使用一个修真:

>>> list(k for k, g in itertools.groupby(x for x in numbers if x != 0)) 
[1, 2, 3, 1, 2] 

如果你也想获得这些职位,那么你必须自己重复列表,正​​如你已经在做的那样。 groupby不会跟踪你的情况。

+1

这正是我想象中存在的地方 - 我想到“某处”几乎总是itertools。谢谢。 – Thomas 2011-02-08 19:09:31