pandas 分组排序并保留原始列

场景

需要按照各个省份及全网进行分组,对各个指标的率值进行排序。
其实这一步一般是在sql中完成的,但由于

  1. 要分组排序的列较多,达30列以上,代码十分不简洁,python一两行即可搞定
  2. 连接的数据库为mysql,本身没有row_number() over( paritition by··· ···)的语句,实现起来较为麻烦。
  3. 本次的原始数据每日只有5000行左右并不大

故直接用python将数据down下来进行处理。

实现

按照常理,直接groupby()分组再rank()排序即可

In[12]: result1.groupby(by='省份')[['投诉完结率', '二次投诉率']].rank(ascending=False, method = 'min')
Out[12]: 
     投诉完结率  二次投诉率
0      1.0    4.0
1      1.0    5.0
2      1.0    1.0
3      1.0    2.0
4      1.0    3.0
..     ...    ...
162    1.0    1.0
163    1.0    1.0
164    1.0    1.0
165    1.0    1.0
166    1.0    1.0

[167 rows x 2 columns]

但实际上得到的结果与sum() mean() max()等聚合运算得到的结果并不相同,这些聚合运算返回的Series或DataFrame的index为“by=”的列。每一组仅返回一行数据。

In[20]: result1.groupby(by='省份').max()[['投诉完结率', '二次投诉率']].head()
Out[20]: 
       投诉完结率   二次投诉率
省份               
上海       1.0  0.0121
云南       1.0  0.0244
全网       1.0  0.0120
内蒙古      1.0  0.0323
北京       1.0  0.0084

但rank()方法在原本数据的基础上每一行都返回一个排名,最后得到的数据index仍为原本的index,其他列是不显示的。

为了在结果中显示其他列,有两种方法:

  1. 如果需要将上述结果join回原result1,直接按index进行join/merge/concat即可, 但不可使用result1[['rank1','rank2']]=result1.groupby(by='省份')[['投诉完结率', '二次投诉率']].rank(ascending=False, method = 'min')这种方式直接增加一列,行的顺序并不能自动对齐 ;
  2. 如仅需一列或几列+计算得到的排名,而不需要原数据中其他列,则对result1在分组之前,将需要的列set_index更为简便
In [14]: result1.set_index(['省份','公司名称']).groupby(by='002省份')[['投诉完结率', '二次投诉率']]\
.rank(ascending=False, method = 'min')
Out[14]: 
                 投诉完结率  二次投诉率
省份   公司名称              
全网      s       1.0    4.0
        b       1.0    5.0
        yd       1.0    1.0
        y       1.0    2.0
        z       1.0    3.0
...                ...    ...
香港特别行政区 b       1.0    1.0
        s       1.0    1.0
        z       1.0    1.0
台湾      z       1.0    1.0
        yd       1.0    1.0

[167 rows x 2 columns]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值