我有以下数据框:
import pandas as pd
cols = 'id,seq,msg'.split(',')
data = [
['001',1,'abc aaa'],
['001',2,'bcd bbb'],
['001',3,'cde ccc'],
['001',1,'def ddd'],
['001',2,'efg eee'],
['001',3,'fgh fff'],
['001',4,'ghi ggg'],
['002',1,'hij hhh'],
['002',2,'ijk iii'],
['002',3,'jkl jjj']
]
df = pd.DataFrame(data,columns=cols)
print(df)
输出:
id seq msg
0 001 1 abc aaa
1 001 2 bcd bbb
2 001 3 cde ccc
3 001 1 def ddd
4 001 2 efg eee
5 001 3 fgh fff
6 001 4 ghi ggg
7 002 1 hij hhh
8 002 2 ijk iii
9 002 3 jkl jjj
如何获得如下输出:
id seq msg msg_num
0 001 1 abc aaa 1
1 001 2 bcd bbb 1
2 001 3 cde ccc 1
3 001 1 def ddd 2
4 001 2 efg eee 2
5 001 3 fgh fff 2
6 001 4 ghi ggg 2
7 002 1 hij hhh 3
8 002 2 ijk iii 3
9 002 3 jkl jjj 3
在上述数据帧中,id#001下有两条消息,id#002下有一条消息。seq
字段在id
字段之后排序。 msg
字段的多行创建一条消息。每当有新消息开始时,seq#都会更改。
答案 0 :(得分:3)
IIUC
df.seq.diff().lt(0).cumsum().add(1)
Out[203]:
0 1
1 1
2 1
3 2
4 2
5 2
6 2
7 3
8 3
9 3
Name: seq, dtype: int64
答案 1 :(得分:2)
IIUC,您每次df.seq
重新启动时都会计算一条新消息,因此您可以这样做:
df['msg_num'] = df.groupby([e - i for i, e in enumerate(df.seq)], sort=False).ngroup() + 1
print(df)
输出
id seq msg msg_num
0 001 1 abc aaa 1
1 001 2 bcd bbb 1
2 001 3 cde ccc 1
3 001 1 def ddd 2
4 001 2 efg eee 2
5 001 3 fgh fff 2
6 001 4 ghi ggg 2
7 002 1 hij hhh 3
8 002 2 ijk iii 3
9 002 3 jkl jjj 3
这里的关键思想是:
[e - i for i, e in enumerate(df.seq)]
可帮助您确定连续的上升运行。或者,您可以这样做:
df['msg_num'] = df.groupby(df.seq - df.seq.index, sort=False).ngroup() + 1
答案 2 :(得分:2)
使用:
df['msg_num']=(df.seq==1).cumsum()
如果它并不总是以1开头:
#import numpy as np
df['msg_num']=(df.seq<df.seq.shift(fill_value=np.inf)).cumsum()
print(df)
id seq msg msg_num
0 1 1 abc aaa 1
1 1 2 bcd bbb 1
2 1 3 cde ccc 1
3 1 1 def ddd 2
4 1 2 efg eee 2
5 1 3 fgh fff 2
6 1 4 ghi ggg 2
7 2 1 hij hhh 3
8 2 2 ijk iii 3
9 2 3 jkl jjj 3