使用 python 为组中的每个元素添加一个序列号
Add a sequence number to each element in a group using python
我有一个数据框,每个人都有多个记录。我想为python中的每个人枚举序列中的记录。本质上,我想在以下 table:
中创建 'sequence' 列
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 语句,但到目前为止还没有成功。谢谢!
问题是如何对多列数据进行排序。
一个简单的技巧是对 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
我偶然发现了简单得令人尴尬的答案。 groupby 语句有一个 'cumcount()' 选项,它将枚举组项目。
df['sequence']=df.groupby('patient').cumcount()
需要注意的是,记录必须按照您希望的顺序排列。
首先,您想将日期列转换为 pandas 日期时间(而不是字符串):
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
(或者如果我们保存了初始 DataFrame 的索引,我们可以重新索引):*
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
这将从 1 而不是 0 开始排序。
df['sequence']=df.groupby('patient').cumcount()+1
我有一个数据框,每个人都有多个记录。我想为python中的每个人枚举序列中的记录。本质上,我想在以下 table:
中创建 'sequence' 列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 语句,但到目前为止还没有成功。谢谢!
问题是如何对多列数据进行排序。
一个简单的技巧是对 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
我偶然发现了简单得令人尴尬的答案。 groupby 语句有一个 'cumcount()' 选项,它将枚举组项目。
df['sequence']=df.groupby('patient').cumcount()
需要注意的是,记录必须按照您希望的顺序排列。
首先,您想将日期列转换为 pandas 日期时间(而不是字符串):
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
(或者如果我们保存了初始 DataFrame 的索引,我们可以重新索引):*
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
这将从 1 而不是 0 开始排序。
df['sequence']=df.groupby('patient').cumcount()+1