繁体   English   中英

如何基于一组行在Pandas DataFrame中新建列

[英]How to create a new column in Pandas DataFrame based on a group of rows

我有以下数据框:

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)

Output:

    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

如何获得 output 如下所示:

    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 # 就会发生变化。

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

IIUC,每次df.seq重新启动时,您都会计算一条新消息,因此您可以这样做:

df['msg_num'] = df.groupby([e - i for i, e in enumerate(df.seq)], sort=False).ngroup() + 1
print(df)

Output

    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

利用:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM