2015-03-30 220 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 
相關問題