比较groupby的第一行和最后一行并创建新值



我有一个具有多个值的数据帧,希望按"电子邮件"列分组,检索第一行和最后一行,并进行比较以查看类别列的状态是否发生了更改。例如,如果类别是从MGR到MGR,则没有变化。如果类别从EMP变为MGR,则反映了状态的变化。

date                 email               category
13-04-2018            johnson@abc.com     MGR
13-04-2018            linsay@abc.com      EMP
18-04-2018            kelphil@abc.com     EMP
20-04-2018            rsling@abc.com      MGR
11-01-2019            johnson@abc.com     MGR
15-10-2019            johnson@abc.com     MGR
16-11-2019            kelphil@abc.com     MGR
31-01-2020            sanson@abc.com      EMP
02-05-2020            rsling@abc.com      MGR
05-08-2020            rsling@abc.com      MGR
14-02-2021            sanson@abc.com      MGR
15-02-2021            linsay@abc.com      MGR

想要得到以下结果

date                 email               category    status
13-04-2018            johnson@abc.com     MGR        no change
15-10-2019            johnson@abc.com     MGR        no change
13-04-2018            linsay@abc.com      EMP        change
15-02-2021            linsay@abc.com      MGR        change
18-04-2018            kelphil@abc.com     EMP        change 
16-11-2019            kelphil@abc.com     MGR        change 
20-04-2018            rsling@abc.com      MGR        no change
05-08-2020            rsling@abc.com      MGR        no change
31-01-2020            sanson@abc.com      EMP        change 
14-02-2021            sanson@abc.com      MGR        change

我尝试了以下代码,但它似乎只检索基于groupby的第一行和最后一行。有什么方法可以比较第一行和最后一行的值吗?

#get the first and last row of the groupby
df2 = df.groupby('email', as_index=False).nth([0,-1])

感谢任何形式的帮助,谢谢。

不确定它是否足够有效,但它运行良好。

def check_status(group):
selected = [False] * len(group)
selected[0] = selected[-1] = True
new_group = group[selected]
new_group['status'] = 'change' if new_group.category.is_unique else 'no change'
return new_group
print(df.groupby('email').apply(check_status).reset_index(drop=True))

try:

这将检查groupby元素是否具有连续值(值是否相同(,如果有任何更改,它将设置标志。

fl = lambda s: s.iloc[[0,-1]]
res = df.groupby('email')['category'].apply(lambda x: (fl(x).shift(1).ne(fl(x)) & (fl(x).nunique()>1)))
res.index = res.index.droplevel()
df['status'] = res
df.dropna(inplace=True)
df['status'] = np.where(df.status,  'Change', 'No Change')

df.sort_values(by='mail'(:

更改//tr>更改改//tr>2018年4月13日linsay@abc.com电磁脉冲改//tr>更改//tr>更改改//tr>
0MGR
515-10-2019johnson@abc.comMGR
22018年4月18日kelphil@abc.com电磁脉冲
616-11-2019kelphil@abc.comMGR
112021年2月15日linsay@abc.comMGR
32018年4月20日rsling@abc.comMGR
905-08-2020rsling@abc.comMGR
7102021年2月14日sanson@abc.comMGR

最新更新