首页 > 解决方案 > 在Python列中检索具有重复值的倒数第二个唯一值

问题描述

我有一个包含电子邮件地址、日期和工作职能的数据集。热衷于获取当前工作职能和以前的工作职能(与当前工作职能不同的价值,以及在当前工作职能之前持有的工作职能)。例如,john.k@abc.com 目前是 swe_mgr2,之前的工作职能是 swe_mgr1。我也热衷于捕捉以前工作职能的持续时间。由于以随机方式捕获的开始日期,持续时间难以计算,但可以根据上一个工作职能的开始日期的第一行直到当前工作职能的开始日期的第一行捕获. 例如,john.k@abc.com 之前的工作职能是 swe_mgr1,从 30-08-2018 持续到 01-06-2019(即 10 个月)。

数据集

email              startdate       jobfunction
john.k@abc.com     01-01-2018      swe_ic1
john.k@abc.com     01-03-2018      swe_ic2
john.k@abc.com     30-08-2018      swe_mgr1
john.k@abc.com     01-06-2019      swe_mgr2  
john.k@abc.com     01-06-2020      swe_mgr2
greg.h@abc.com     30-01-2018      mkt_ic2
greg.h@abc.com     01-06-2018      mkt_ic3 
greg.h@abc.com     07-09-2018      mkt_mgr1
greg.h@abc.com     12-12-2018      mkt_mgr2
greg.h@abc.com     15-01-2019      mkt_mgr2 
greg.h@abc.com     05-06-2019      mkt_mgr2
greg.h@abc.com     01-06-2020      mkt_mgr3
joseph.c@abc.com   01-06-2019      sales_ic1
joseph.c@abc.com   01-06-2020      sales_mgr1

预期的输出是

email             current_function     previous_function      duration_previous_function
john.k@abc.com    swe_mgr2             swe_mgr1                10mths
greg.h@abc.com    mkt_mgr3             mkt_mgr2                18mths
joseph.c@abc.com  sales_mgr1           sales_ic1               12mths

我被困在试图获得以前的工作职能的第一步,

此代码似乎适用于检索当前的工作职能,但不是以前的工作职能

df2 = df.groupby('email').last().sort_index().reset_index().drop_duplicates()

我还想知道这是否可以通过遍历每个电子邮件地址来实现,但下面的代码也不能正常工作

emails = df['email']
assigndate = df['startdate']
jobname = df['jobfunction']

for i in emails:
    prevjob = jobname.apply(lambda x: x.unique([-2]))

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

标签: pythonpandasdataframefor-looppandas-groupby

解决方案


您可以在转换为日期时间后首先对列进行排序DataFrame.sort_values并获取最后的重复项DataFrame.drop_duplicates,然后为过滤器的前 2 行创建计数器,然后在由and创建的GroupBy.cumcount新级别中创建计数器:MultiIndexDataFrame.set_indexDataFrame.unstack

df['startdate'] = pd.to_datetime(df['startdate'], dayfirst=True)

df = (df.sort_values(['email','startdate'], ascending=[True, False])
        .drop_duplicates(['email','jobfunction'], keep='last'))
df['g'] = df.groupby('email').cumcount()
df1 = df[df['g'].lt(2)].copy()
df1 = (df1.set_index(['email','g'])
          .unstack()
          .rename(columns={0:'current',1:'previous'}))
df1.columns = [f'{b}_{a}' for a,b in df1.columns]
df1 = df1.reset_index()

DataFrame.pop最后减去通过和转换为月份期间的列Series.dt.to_period

df1['duration_previous_function'] = (df1.pop('current_startdate')
                                        .dt.to_period('m')
                                        .astype('int')
                                        .sub(df1.pop('previous_startdate')
                                                .dt.to_period('m')
                                                .astype('int')))
print (df1)
              email current_jobfunction previous_jobfunction  \
0    greg.h@abc.com            mkt_mgr3             mkt_mgr2   
1    john.k@abc.com            swe_mgr2             swe_mgr1   
2  joseph.c@abc.com          sales_mgr1            sales_ic1   

   duration_previous_function  
0                          18  
1                          10  
2                          12  

推荐阅读