回顾数据框中的上一行并选择特定的记录

时间:2019-05-20 05:03:47

标签: python pandas

我有一个数据框df,看起来像:

           name     year    dept         metric
0   Steve Jones     2018       A    0.703300236
1   Steve Jones     2019       A    0.255587222
2   Jane Smith      2018       A    0.502505934
3   Jane Smith      2019       B    0.698808749
4   Barry Evans     2019       B    0.941325241
5   Tony Edwards    2017       B    0.880940126
6   Tony Edwards    2018       B    0.649086123
7   Tony Edwards    2019       A    0.881365905

我想创建两个新的数据框,其中包含某人从部门A移到B以及另一个人从部门B移到A的记录。因此,我想要的输出是:

            name        year    dept         metric
0     Jane Smith        2018       A    0.502505934
1     Tony Edwards      2019       B    0.649086123

            name        year    dept         metric
0     Jane Smith        2019       B    0.698808749
1   Tony Edwards        2018       B    0.881365905

在一个数据框中捕获某人在其旧部门中的最后一年的记录,而在另一部门中捕获在新部门中的第一年的记录。记录按名称和年份排序,因此顺序正确。

我尝试过:

for row in agg_data.rows:

    df['match'] = np.where(df.dept == 'A' and  df.dept.shift() =='B','1')
    df['match'] = np.where(df.dept == 'B' and  df.dept.shift() =='A','2')

,然后将记录选择到一个数据框中,但是我可以使用它。

3 个答案:

答案 0 :(得分:1)

我相信您需要:

df = df[df.groupby('name')['dept'].transform('nunique') > 1]
df = df.drop_duplicates(['name','dept'], keep='last')

df1 = df.drop_duplicates('name')
print (df1)
           name  year dept    metric
2    Jane Smith  2018    A  0.502506
6  Tony Edwards  2018    B  0.649086

df2 = df.drop_duplicates('name', keep='last')
print (df2)
           name  year dept    metric
3    Jane Smith  2019    B  0.698809
7  Tony Edwards  2019    A  0.881366

答案 1 :(得分:0)

您可以将初始数据框自身移动以在同一行上具有连续的行。然后,您要求要要求名称相同的部门,并获得预期行之一的索引,另一行只有一个相邻索引。它给出:

df = agg_data.join(agg_data.shift(), rsuffix='_old')

df1 = df[(df.name_old==df.name)&(df.dept_old=='A')&(df.dept=='B')]
print(pd.concat([agg_data.loc[df1.index], agg_data.loc[df1.index-1]]
                ).sort_index())

df2 = df[(df.name_old==df.name)&(df.dept_old=='B')&(df.dept=='A')]
print(pd.concat([agg_data.loc[df2.index], agg_data.loc[df2.index-1]]
                ).sort_index())

具有以下输出:

         name  year dept    metric
2  Jane Smith  2018    A  0.502506
3  Jane Smith  2019    B  0.698809
           name  year dept    metric
6  Tony Edwards  2018    B  0.649086
7  Tony Edwards  2019    A  0.881366

答案 2 :(得分:0)

我想出了一个使用drop_duplicatesgroupbyrank的解决方案。在df2

中,在rank=2上创建df1并在rank==1name上创建df2
df['rk'] = df.sort_values(['name', 'dept', 'year']).drop_duplicates(['name', 'dept'], keep='last').groupby('name').year.rank()
df2 = df[df.rk.eq(2)].drop('rk', 1)
df1 = df[df.rk.eq(1) & df.name.isin(df2.name)].drop('rk', 1)


df1:
           name  year dept    metric
2    Jane Smith  2018    A  0.502506
6  Tony Edwards  2018    B  0.649086

df2:
           name  year dept    metric
3    Jane Smith  2019    B  0.698809
7  Tony Edwards  2019    A  0.881366