2015-03-30 222 views
5

我有一个个人的数据框,每个人都有多个记录。我想枚举每个人在Python中的序列中的记录。从本质上讲,我想在下表中,以创建“序列”列:使用python向组中的每个元素添加序列号

patient date  sequence 
145  20Jun2009  1 
145  24Jun2009  2 
145  15Jul2009  3 
582  09Feb2008  1 
582  21Feb2008  2 
987  14Mar2010  1 
987  02May2010  2 
987  12May2010  3 

这基本上是here同样的问题,但我在Python的工作,无法实现SQL解决方案。我怀疑我可以使用具有可迭代计数的groupby语句,但迄今为止不成功。谢谢!

回答

0

问题是如何排序多列数据。

一个简单的技巧是使用参数sorted函数key

您将按照从数组列中构建的字符串进行排序。

rows = ...# your source data 

def date_to_sortable_string(date): 
    # use datetime package to convert string to sortable date. 
    pass 

# Assume x[0] === patient_id and x[1] === encounter date 

# Sort by patient_id and date 
rows_sorted = sorted(rows, key=lambda x: "%0.5d-%s" % (x[0], date_to_sortable_string(x[1]))) 

for row in rows_sorted: 
    print row 
17

我偶然发现了一个令人尴尬的简单答案。 groupby语句有一个'cumcount()'选项,它将枚举组项。

df['sequence']=df.groupby('patient').cumcount() 

需要注意的是记录必须按您希望枚举的顺序进行。

+0

是正确的答案:) – 2015-04-02 04:33:26

+0

哇什么救星 - 运行无限比我的任何黑客都快 – Owen 2017-01-17 20:44:45

1

首先要日期列转换成为大熊猫日期时间(而不是字符串):

In [11]: pd.to_datetime(df['date'], format='%d%b%Y') 
Out[11]: 
0 2009-06-20 
1 2009-06-24 
2 2009-07-15 
3 2008-02-09 
4 2008-02-21 
5 2010-03-14 
6 2010-05-02 
7 2010-05-12 
Name: date, dtype: datetime64[ns] 

注:参见docs可能的格式选项。

In [12]: df['date'] = pd.to_datetime(df['date'], format='%d%b%Y') 

In [13]: df 
Out[13]: 
    patient  date sequence 
0  145 2009-06-20   1 
1  145 2009-06-24   2 
2  145 2009-07-15   3 
3  582 2008-02-09   1 
4  582 2008-02-21   2 
5  987 2010-03-14   1 
6  987 2010-05-02   2 
7  987 2010-05-12   3 

如果不按日期顺序排列(每个病人),我会先对它进行排序:

In [14]: df = df.sort('date') 

现在你可以GROUPBY和cumcount:

In [15]: g = df.groupby('patient') 

In [16]: g.cumcount() + 1 
Out[16]: 
2 1 
3 2 
0 1 
1 2 
4 1 
5 2 
6 3 
dtype: int64 

哪是你想要的(不包括它的失序):

In [17]: df['sequence'] = g.cumcount() + 1 

In [18]: df 
Out[18]: 
     patient  date sequence 
2  582 2008-02-09   1 
3  582 2008-02-21   2 
0  145 2009-06-24   1 
1  145 2009-07-15   2 
4  987 2010-03-14   1 
5  987 2010-05-02   2 
6  987 2010-05-12   3 

要重新排列(虽然你可能不需要)使用sort_index(或者,如果我们保存的初始数据帧的指数,我们可以重新索引):*

In [19]: df.sort_index() 
Out[19]: 
    patient  date sequence 
0  145 2009-06-24   1 
1  145 2009-07-15   2 
2  582 2008-02-09   1 
3  582 2008-02-21   2 
4  987 2010-03-14   1 
5  987 2010-05-02   2 
6  987 2010-05-12   3 
相关问题