将两个数据框连接在一起,并在连接时递增排名。

3

我有两个数据框

数据框1:

index cust_id   rank opt
0   customer_1  1   test1
2   customer_1  2   test3 
3   customer_1  3   test4
4   customer_2  1   test1
5   customer_2  2   test4   
7   customer_2  3   test3   
9   customer_3  1   test3   
10  customer_3  2   test4   
11  customer_3  3   test1

数据框2:

index cust_id rank opt
1   customer_1  1  new_opt
2   customer_2  2  new_opt
3   customer_3  3  new_opt

我希望将这两个数据框合并在一起,并获得以下输出结果:
index cust_id   rank opt
0   customer_1  1   new_opt
1   customer_1  2   test1
2   customer_1  3   test3 
3   customer_1  4   test4
4   customer_2  1   test1
5   customer_2  2   new_opt
6   customer_2  3   test4   
7   customer_2  4   test3   
8   customer_3  1   test3   
9   customer_3  2   test4
10  customer_3  3   new_opt
11  customer_3  4   test1

基本上我希望数据框2的排名保持不变,在将数据框连接在一起后,数据框1中剩余选项的排名会增加。
任何帮助将不胜感激!
1个回答

4

在两个DataFrame中使用密集排名,将第一个DataFrame连接到第二个DataFrame上并进行排序。这可以确保df2中的行出现在df1中排名相似的行之上。然后,在组内使用cumcount进行新排名。

df = pd.concat([df2, df1], ignore_index=True).sort_values(['cust_id', 'rank'])
df['rank'] = df.groupby('cust_id').cumcount()+1

       cust_id  rank      opt
0   customer_1     1  new_opt
3   customer_1     2    test1
4   customer_1     3    test3
5   customer_1     4    test4
6   customer_2     1    test1
1   customer_2     2  new_opt
7   customer_2     3    test4
8   customer_2     4    test3
9   customer_3     1    test3
10  customer_3     2    test4
2   customer_3     3  new_opt
11  customer_3     4    test1

如果您想要将排名高于 new_opt 的所有行的排名总体上加 1,而不考虑初始排名,我们可以使用 groupby.apply 来实现这一点。第一步相同,但现在我们使用 cummax 在组中 new_opt 后添加 1 到所有行。这将导致与以上相同的输出结果。

df = pd.concat([df2, df1], ignore_index=True).sort_values(['cust_id', 'rank'])
df['rank'] = (df['rank'] 
              + (df.opt.eq('new_opt')
                   .groupby(df.cust_id)
                   .apply(lambda x: x.shift().cummax()).fillna(0).astype(int)))

1
顶部的那个正是我想要的,它有效了,谢谢! - pandas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接