计算每个销售小组每个成员销售业绩占比及组内排名

CDA老师1

Python
# 计算每个销售小组每个成员销售业绩占比及组内排名 ```                                           ----------- 每篇一个pandas小技巧之二,分组数据计算组内占比及排序 ``` **文中代码使用的pandas版本1.3.2** ## 需求背景: **某公司有若干销售小组,现有所有销售人员某月的销售额,现需要计算每位成员的销售额占本组总销售额的比例,并且计算每位成员在本组内销售额的排名。** **为了便于更直观的查看代码效果,从所有数据中截取一小部分数据作为示例。** **原始数据如下:** ``` df ``` ``` .dataframe tbody tr th {   vertical-align: top; } .dataframe thead th {   text-align: right; } ``` **** | 序号 | 姓名 | 组别 | 销售额 | | ---- | ------ | ----- | ------ | | 17 | 王右江 | 第1组 | 69 | | 18 | 吴东飞 | 第1组 | 14 | | 19 | 张中名 | 第4组 | 97 | | 20 | 李左河 | 第4组 | 27 | | 21 | 常一名 | 第2组 | 83 | | 22 | 吴上江 | 第1组 | 65 | | 23 | 张中海 | 第1组 | 29 | | 24 | 张二海 | 第2组 | 10 | | 25 | 李南河 | 第2组 | 29 | | 26 | 蔡北江 | 第4组 | 32 | | 27 | 王上河 | 第4组 | 72 | | 28 | 张东名 | 第4组 | 76 | | 29 | 蔡右海 | 第2组 | 47 | | 30 | 梁二海 | 第1组 | 56 | | 31 | 梁东名 | 第2组 | 43 | **
** **查看数据中一共有几个分组以及每个分组中有几位员工,代码如下:** ``` df["组别"].value_counts() ``` ``` 第1组   5 第4组   5 第2组   5 Name: 组别, dtype: int64 ``` ## 计算组内占比 **截取的数据中一共包含三个小组,每个小组分别有5位员工。** **以这部分数据为例,计算每位员工的销售额占本组总销售额的占比。用到的具体代码如下:** ``` df.groupby("组别")["销售额"].transform(lambda x:x/x.sum()) ``` ``` 序号 17   0.296137 18   0.060086 19   0.319079 20   0.088816 21   0.391509 22   0.278970 23   0.124464 24   0.047170 25   0.136792 26   0.105263 27   0.236842 28   0.250000 29   0.221698 30   0.240343 31   0.202830 Name: 销售额, dtype: float64 ``` **groupby对象的transform方法和apply方法类似,接收的参数都是函数,都是用分组后每组的dataframe作为传递给transform或者apply的函数的参数。** **如上述代码汇总,就是把每个分组的dataframe作为参数传递给了lambda函数,而lambda函数的作用是计算每个销售额与组内总销售额的比值,得到的即为每位员工销售额占组内总销售额的占比。** **把上述代码计算出的结果添加到原表当中去,代码如下:** ``` df["组内占比"] = df.groupby("组别")["销售额"].transform(lambda x:x/x.sum()) ``` **下表为添加后的结果展示:** ``` df ``` ``` .dataframe tbody tr th {   vertical-align: top; } .dataframe thead th {   text-align: right; } ``` **** | 序号 | 姓名 | 组别 | 销售额 | 组内占比 | | ---- | ------ | ----- | ------ | -------- | | 17 | 王右江 | 第1组 | 69 | 0.296137 | | 18 | 吴东飞 | 第1组 | 14 | 0.060086 | | 19 | 张中名 | 第4组 | 97 | 0.319079 | | 20 | 李左河 | 第4组 | 27 | 0.088816 | | 21 | 常一名 | 第2组 | 83 | 0.391509 | | 22 | 吴上江 | 第1组 | 65 | 0.278970 | | 23 | 张中海 | 第1组 | 29 | 0.124464 | | 24 | 张二海 | 第2组 | 10 | 0.047170 | | 25 | 李南河 | 第2组 | 29 | 0.136792 | | 26 | 蔡北江 | 第4组 | 32 | 0.105263 | | 27 | 王上河 | 第4组 | 72 | 0.236842 | | 28 | 张东名 | 第4组 | 76 | 0.250000 | | 29 | 蔡右海 | 第2组 | 47 | 0.221698 | | 30 | 梁二海 | 第1组 | 56 | 0.240343 | | 31 | 梁东名 | 第2组 | 43 | 0.202830 | **
** **如果希望“组内占比”列的数据展现形式是百分数的形式,可以用字符串的格式化对数据格式进行修改。需要注意修改后的数据不再是数值型,而是字符串,不能再进行聚合运算,所以转换的时候要慎重。转换的代码如下:** ``` df["组内占比"].apply(lambda x:"{:.2%}".format(x)) ``` ``` 序号 17   29.61% 18     6.01% 19   31.91% 20     8.88% 21   39.15% 22   27.90% 23   12.45% 24     4.72% 25   13.68% 26   10.53% 27   23.68% 28   25.00% 29   22.17% 30   24.03% 31   20.28% Name: 组内占比, dtype: object ``` ## 计算组内排名 **计算组内排名,需要用到groupby对象的rank方法,该方法是专门计算排名的方法。依据哪一列计算排名,就用groupby对象的哪一列调用该方法即可。** **接前边的例子,要计算每位员工的销售额在组内的排名,只需要按照“组别”列进行分组,然后按照“销售额”列进行排名即可,新增排名列,排名数据添加到原表中,代码如下:** ``` df["组内排名"] = df.groupby("组别")["销售额"].rank(ascending=False).astype(int) #ascending=False表示降序排序进行排名 #由于排名后的数据类型是浮点型,用astype方法修改数据类型为整型 ``` **注意,rank排名的方式分好几种,有时候排名会出现0.5,所以不是每次排名的结果都可以转换成整型,详情见文章最后,对rank排名方式汇总的代码结果中有展现。** **查看添加排名数据后的df表:** ``` df ``` ``` .dataframe tbody tr th {   vertical-align: top; } .dataframe thead th {   text-align: right; } ``` **** | 序号 | 姓名 | 组别 | 销售额 | 组内占比 | 组内排名 | | ---- | ------ | ----- | ------ | -------- | -------- | | 17 | 王右江 | 第1组 | 69 | 0.296137 | 1 | | 18 | 吴东飞 | 第1组 | 14 | 0.060086 | 5 | | 19 | 张中名 | 第4组 | 97 | 0.319079 | 1 | | 20 | 李左河 | 第4组 | 27 | 0.088816 | 5 | | 21 | 常一名 | 第2组 | 83 | 0.391509 | 1 | | 22 | 吴上江 | 第1组 | 65 | 0.278970 | 2 | | 23 | 张中海 | 第1组 | 29 | 0.124464 | 4 | | 24 | 张二海 | 第2组 | 10 | 0.047170 | 5 | | 25 | 李南河 | 第2组 | 29 | 0.136792 | 4 | | 26 | 蔡北江 | 第4组 | 32 | 0.105263 | 4 | | 27 | 王上河 | 第4组 | 72 | 0.236842 | 3 | | 28 | 张东名 | 第4组 | 76 | 0.250000 | 2 | | 29 | 蔡右海 | 第2组 | 47 | 0.221698 | 2 | | 30 | 梁二海 | 第1组 | 56 | 0.240343 | 3 | | 31 | 梁东名 | 第2组 | 43 | 0.202830 | 3 | **
** **提取其中一个分组,查看排名结果,如下:** ``` df.groupby("组别").get_group("第1组") ``` ``` .dataframe tbody tr th {   vertical-align: top; } .dataframe thead th {   text-align: right; } ``` **** | 序号 | 姓名 | 组别 | 销售额 | 组内占比 | 组内排名 | | ---- | ------ | ----- | ------ | -------- | -------- | | 17 | 王右江 | 第1组 | 69 | 0.296137 | 1 | | 18 | 吴东飞 | 第1组 | 14 | 0.060086 | 5 | | 22 | 吴上江 | 第1组 | 65 | 0.278970 | 2 | | 23 | 张中海 | 第1组 | 29 | 0.124464 | 4 | | 30 | 梁二海 | 第1组 | 56 | 0.240343 | 3 | **** **rank方法的常用参数除了ascending用来指定排序方向之外,还有另一个常用参数method,即排名的方式,假如上述例子中,有两个人的销售额一样,比如都是排名第二,那么允许有并列第二,还是不允许有并列情况出现;如果允许有并列情况出现,那么,下一个名次人的排名是第三还是第四?method参数就是解决这些问题,具体的参数详情见下边官网的例子:** ``` df1 = pd.DataFrame({ "group": ["a", "a", "a", "a", "a", "b", "b", "b", "b", "b"], "value": [2, 4, 2, 3, 5, 1, 2, 4, 1, 5],}) df1 ``` ``` .dataframe tbody tr th {   vertical-align: top; } .dataframe thead th {   text-align: right; } ``` **** |
group | value | | ---------- | ----- | | 0 | a | | 1 | a | | 2 | a | | 3 | a | | 4 | a | | 5 | b | | 6 | b | | 7 | b | | 8 | b | | 9 | b | **** **通过循环把按照不同排名方式的排名结果都添加到原表中。** ``` for method in ['average', 'min', 'max', 'dense', 'first']:    df1[f'{method}_rank'] = df1.groupby('group')['value'].rank(method,ascending = False) df1 ``` ``` .dataframe tbody tr th {   vertical-align: top; } .dataframe thead th {   text-align: right; } ``` **** |
group | value | average_rank | min_rank | max_rank | dense_rank | first_rank | | ---------- | ----- | ------------ | -------- | -------- | ---------- | ---------- | | 0 | a | 2 | 4.5 | 4.0 | 5.0 | 4.0 | | 1 | a | 4 | 2.0 | 2.0 | 2.0 | 2.0 | | 2 | a | 2 | 4.5 | 4.0 | 5.0 | 4.0 | | 3 | a | 3 | 3.0 | 3.0 | 3.0 | 3.0 | | 4 | a | 5 | 1.0 | 1.0 | 1.0 | 1.0 | | 5 | b | 1 | 4.5 | 4.0 | 5.0 | 4.0 | | 6 | b | 2 | 3.0 | 3.0 | 3.0 | 3.0 | | 7 | b | 4 | 2.0 | 2.0 | 2.0 | 2.0 | | 8 | b | 1 | 4.5 | 4.0 | 5.0 | 4.0 | | 9 | b | 5 | 1.0 | 1.0 | 1.0 | 1.0 | **** **为了方便查看method参数不同取值下得到的不同结果,这里按照“group”和“value”进行排序,并且指定了排序依据分别为升序和降序,这样一眼就能看出不同的取值对应的结果。** ``` df1.sort_values(["group","value"],ascending = [True,False]) ``` ``` .dataframe tbody tr th {   vertical-align: top; } .dataframe thead th {   text-align: right; } ``` **** | | group | value | average_rank | min_rank | max_rank | dense_rank | first_rank | | --- | ------- | ------- | -------------- | ---------- | ---------- | ------------ | ------------ | | 4 | a | 5 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | | 1 | a | 4 | 2.0 | 2.0 | 2.0 | 2.0 | 2.0 | | 3 | a | 3 | 3.0 | 3.0 | 3.0 | 3.0 | 3.0 | | 0 | a | 2 | 4.5 | 4.0 | 5.0 | 4.0 | 4.0 | | 2 | a | 2 | 4.5 | 4.0 | 5.0 | 4.0 | 5.0 | | 9 | b | 5 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | | 7 | b | 4 | 2.0 | 2.0 | 2.0 | 2.0 | 2.0 | | 6 | b | 2 | 3.0 | 3.0 | 3.0 | 3.0 | 3.0 | | 5 | b | 1 | 4.5 | 4.0 | 5.0 | 4.0 | 4.0 | | 8 | b | 1 | 4.5 | 4.0 | 5.0 | 4.0 | 5.0 | ****
0.0270 3 0 关注作者 收藏 2022-12-19   阅读量: 417

评论(0)


暂无数据

热门用户

博客推荐