计算各类别产品销售额的三种占比

计算各类别产品销售额的三种占比

需求背景

公司销售多种品牌的多种产品,现需要计算每个品牌下每种产品销售额的组内占比,组内累计占比和每组销售额占总销售的比例。以下列数据为例,简单解释这三种需求

df

.dataframe tbody tr th {
vertical-align: top;
}

.dataframe thead th {
text-align: right;
}

销售日期 品牌 类别 款号 销量
0 2021-01-01 A T恤 1001 63
1 2021-01-02 A T恤 1002 21
2 2021-01-03 A T恤 1003 88
3 2021-01-04 B T恤 1004 88
4 2021-01-05 B T恤 1005 17
5 2021-01-06 B T恤 1006 98
6 2021-01-07 A T恤 1007 100
7 2021-01-08 A T恤 1008 95
8 2021-01-09 B T恤 1009 63
9 2021-01-10 B T恤 1010 86
10 2021-01-11 A 裤子 1011 77
11 2021-01-12 A 裤子 1012 81
12 2021-01-13 A 连衣裙 1013 51
13 2021-01-14 A 连衣裙 1014 93
14 2021-01-15 A 裤子 1015 96
15 2021-01-16 A 裤子 1016 39
16 2021-01-17 A 连衣裙 1017 48
17 2021-01-18 A 连衣裙 1018 98
18 2021-01-19 A 连衣裙 1019 57
19 2021-01-20 B 连衣裙 1020 12
20 2021-01-21 B 连衣裙 1021 82
21 2021-01-22 B 毛衣 1022 36
22 2021-01-23 B 毛衣 1023 66
23 2021-01-24 B 毛衣 1024 97
24 2021-01-25 B 连衣裙 1025 72
25 2021-01-26 B 连衣裙 1026 53
26 2021-01-27 B 毛衣 1027 100
27 2021-01-28 B 毛衣 1028 10

从上述数据可以看出,该表记录的是每个品牌下每种产品在某日期的销售情况,以品牌A中的连衣裙为例:

计算每一天连衣裙的销售额占连衣裙总销售额的占比

计算每一天连衣裙的销售额占连衣裙总销售额的累计占比

计算品牌A连衣裙的总销售额在所有产品总销售额中的占比

最终的表中,数据行数不变,每一条销售记录后边都添加上该条记录销售额的组内占比、组内累计占比和该品类销售额占所有产品销售额的比例。

首先,把原表中的数据按照品牌、类别和销量进行排序,其中品牌和类别是升序排序,销量降序排序。

不对销量排序也可以,这里为了效果明显,销量也进行了排序。

df1 = df.sort_values([“品牌”,“类别”,“销量”],ascending=[True,True,False])
#对原表按照品牌、类别、销量进行排序,其中品牌和类别升序排序,销量降序排序
组内累计占比
计算组内累计占比,首先按照品牌和类别进行分组,然后计算销量的累计和,用累计和除以分组后销量的总和即可。

计算过程中用到transform,前一篇文章里有介绍过transform的用法,这里不再赘述。

ss = df1.groupby([“品牌”,“类别”])[“销量”].transform(“cumsum”)/df1.groupby([“品牌”,“类别”])[“销量”].transform(“sum”)

按照品牌和类别分组,对分组后的数据按照分组求累计和,再对分组后的数据按照分组求和,两者相除得到组内累计占比,生成一个series

ss
6 0.272480
7 0.531335
2 0.771117
0 0.942779
1 1.000000
14 0.327645
11 0.604096
10 0.866894
15 1.000000
17 0.282421
13 0.550432
18 0.714697
12 0.861671
16 1.000000
5 0.278409
3 0.528409
9 0.772727
8 0.951705
4 1.000000
26 0.323625
23 0.637540
22 0.851133
21 0.967638
27 1.000000
20 0.374429
24 0.703196
25 0.945205
19 1.000000
Name: 销量, dtype: float64
计算的累计占比是series数据结构,其中的元素值都是浮点数,可以把浮点数转化成百分数。

注意在python中,数值型的数据中没有百分数这种数据类型,所以想要以百分数的形式展现,只能把浮点数转化成字符串,运用字符串的格式化方法。

具体代码和代码效果如下:

df1[‘类别累计占比’] = ss.apply(lambda x : format(x,‘.2%’))

得到的累计占比是浮点数形式,修改成百分比形式

df1

.dataframe tbody tr th {
vertical-align: top;
}

.dataframe thead th {
text-align: right;
}

销售日期 品牌 类别 款号 销量 类别累计占比
6 2021-01-07 A T恤 1007 100 27.25%
7 2021-01-08 A T恤 1008 95 53.13%
2 2021-01-03 A T恤 1003 88 77.11%
0 2021-01-01 A T恤 1001 63 94.28%
1 2021-01-02 A T恤 1002 21 100.00%
14 2021-01-15 A 裤子 1015 96 32.76%
11 2021-01-12 A 裤子 1012 81 60.41%
10 2021-01-11 A 裤子 1011 77 86.69%
15 2021-01-16 A 裤子 1016 39 100.00%
17 2021-01-18 A 连衣裙 1018 98 28.24%
13 2021-01-14 A 连衣裙 1014 93 55.04%
18 2021-01-19 A 连衣裙 1019 57 71.47%
12 2021-01-13 A 连衣裙 1013 51 86.17%
16 2021-01-17 A 连衣裙 1017 48 100.00%
5 2021-01-06 B T恤 1006 98 27.84%
3 2021-01-04 B T恤 1004 88 52.84%
9 2021-01-10 B T恤 1010 86 77.27%
8 2021-01-09 B T恤 1009 63 95.17%
4 2021-01-05 B T恤 1005 17 100.00%
26 2021-01-27 B 毛衣 1027 100 32.36%
23 2021-01-24 B 毛衣 1024 97 63.75%
22 2021-01-23 B 毛衣 1023 66 85.11%
21 2021-01-22 B 毛衣 1022 36 96.76%
27 2021-01-28 B 毛衣 1028 10 100.00%
20 2021-01-21 B 连衣裙 1021 82 37.44%
24 2021-01-25 B 连衣裙 1025 72 70.32%
25 2021-01-26 B 连衣裙 1026 53 94.52%
19 2021-01-20 B 连衣裙 1020 12 100.00%

能看到,在dataframe的最后多了一类累计占比。

前一篇的文章中我们已经讨论过组内占比的计算方法,这里我们可以再计算一遍,用来验证累计占比的结果是否正确

组内占比
组内占比计算方法前一篇文章已经讨论过,这里不再赘述,具体代码如下:

df1[“类别组内占比”] = (df1[“销量”]/df1.groupby([“品牌”,“类别”])[“销量”].transform(“sum”)).apply(lambda x : format(x,‘.2%’))
df1
.dataframe tbody tr th {
vertical-align: top;
}

.dataframe thead th {
text-align: right;
}

销售日期 品牌 类别 款号 销量 类别累计占比 类别组内占比
6 2021-01-07 A T恤 1007 100 27.25% 27.25%
7 2021-01-08 A T恤 1008 95 53.13% 25.89%
2 2021-01-03 A T恤 1003 88 77.11% 23.98%
0 2021-01-01 A T恤 1001 63 94.28% 17.17%
1 2021-01-02 A T恤 1002 21 100.00% 5.72%
14 2021-01-15 A 裤子 1015 96 32.76% 32.76%
11 2021-01-12 A 裤子 1012 81 60.41% 27.65%
10 2021-01-11 A 裤子 1011 77 86.69% 26.28%
15 2021-01-16 A 裤子 1016 39 100.00% 13.31%
17 2021-01-18 A 连衣裙 1018 98 28.24% 28.24%
13 2021-01-14 A 连衣裙 1014 93 55.04% 26.80%
18 2021-01-19 A 连衣裙 1019 57 71.47% 16.43%
12 2021-01-13 A 连衣裙 1013 51 86.17% 14.70%
16 2021-01-17 A 连衣裙 1017 48 100.00% 13.83%
5 2021-01-06 B T恤 1006 98 27.84% 27.84%
3 2021-01-04 B T恤 1004 88 52.84% 25.00%
9 2021-01-10 B T恤 1010 86 77.27% 24.43%
8 2021-01-09 B T恤 1009 63 95.17% 17.90%
4 2021-01-05 B T恤 1005 17 100.00% 4.83%
26 2021-01-27 B 毛衣 1027 100 32.36% 32.36%
23 2021-01-24 B 毛衣 1024 97 63.75% 31.39%
22 2021-01-23 B 毛衣 1023 66 85.11% 21.36%
21 2021-01-22 B 毛衣 1022 36 96.76% 11.65%
27 2021-01-28 B 毛衣 1028 10 100.00% 3.24%
20 2021-01-21 B 连衣裙 1021 82 37.44% 37.44%
24 2021-01-25 B 连衣裙 1025 72 70.32% 32.88%
25 2021-01-26 B 连衣裙 1026 53 94.52% 24.20%
19 2021-01-20 B 连衣裙 1020 12 100.00% 5.48%

把组内占比的数据添加到累计占比后,很明显能够看出,我们累计占比的计算结果是正确的。

计算每个分组的销量占总销量的比例
计算每个分组的销售额占所有产品销售额的方法并不难,数据分组后求和,然后和所有产品销售额相除即可。

但是在当前问题中,我们希望让每一条销售记录后边都添加上该类产品销售额在总销售额中的占比,这里用到的也是transform。

这也是transform和apply两个方法之间的一个区别,要实现上述效果,apply做不到,因为apply输出汇总后的数据,两者的具体区别见如下代码:

df1.groupby([“品牌”,“类别”])[“销量”].transform(“sum”)/df1[“销量”].sum()
6 0.194489
7 0.194489
2 0.194489
0 0.194489
1 0.194489
14 0.155273
11 0.155273
10 0.155273
15 0.155273
17 0.183890
13 0.183890
18 0.183890
12 0.183890
16 0.183890
5 0.186539
3 0.186539
9 0.186539
8 0.186539
4 0.186539
26 0.163752
23 0.163752
22 0.163752
21 0.163752
27 0.163752
20 0.116057
24 0.116057
25 0.116057
19 0.116057
Name: 销量, dtype: float64
df1.groupby([“品牌”,“类别”])[“销量”].apply(sum)/df1[“销量”].sum()
品牌 类别
A T恤 0.194489
裤子 0.155273
连衣裙 0.183890
B T恤 0.186539
毛衣 0.163752
连衣裙 0.116057
Name: 销量, dtype: float64
apply也可以计算每个分组的销售额占总销售的比值,但是最终得到得的结果和原表中的数据量不匹配,无法添加到原表中,所以这里需要用transform方法,具体的代码如下:

(df1.groupby([“品牌”,“类别”])[“销量”].transform(“sum”)/df1[“销量”].sum()).apply(lambda x : format(x,‘.2%’))

6 19.45%
7 19.45%
2 19.45%
0 19.45%
1 19.45%
14 15.53%
11 15.53%
10 15.53%
15 15.53%
17 18.39%
13 18.39%
18 18.39%
12 18.39%
16 18.39%
5 18.65%
3 18.65%
9 18.65%
8 18.65%
4 18.65%
26 16.38%
23 16.38%
22 16.38%
21 16.38%
27 16.38%
20 11.61%
24 11.61%
25 11.61%
19 11.61%
Name: 销量, dtype: object

df1[“本组销量占比”] = (df1.groupby([“品牌”,“类别”])[“销量”].transform(“sum”)/df1[“销量”].sum()).apply(lambda x : format(x,‘.2%’))
df1
.dataframe tbody tr th {
vertical-align: top;
}

.dataframe thead th {
text-align: right;
}

销售日期 品牌 类别 款号 销量 类别累计占比 类别组内占比 本组销量占比
6 2021-01-07 A T恤 1007 100 27.25% 27.25% 19.45%
7 2021-01-08 A T恤 1008 95 53.13% 25.89% 19.45%
2 2021-01-03 A T恤 1003 88 77.11% 23.98% 19.45%
0 2021-01-01 A T恤 1001 63 94.28% 17.17% 19.45%
1 2021-01-02 A T恤 1002 21 100.00% 5.72% 19.45%
14 2021-01-15 A 裤子 1015 96 32.76% 32.76% 15.53%
11 2021-01-12 A 裤子 1012 81 60.41% 27.65% 15.53%
10 2021-01-11 A 裤子 1011 77 86.69% 26.28% 15.53%
15 2021-01-16 A 裤子 1016 39 100.00% 13.31% 15.53%
17 2021-01-18 A 连衣裙 1018 98 28.24% 28.24% 18.39%
13 2021-01-14 A 连衣裙 1014 93 55.04% 26.80% 18.39%
18 2021-01-19 A 连衣裙 1019 57 71.47% 16.43% 18.39%
12 2021-01-13 A 连衣裙 1013 51 86.17% 14.70% 18.39%
16 2021-01-17 A 连衣裙 1017 48 100.00% 13.83% 18.39%
5 2021-01-06 B T恤 1006 98 27.84% 27.84% 18.65%
3 2021-01-04 B T恤 1004 88 52.84% 25.00% 18.65%
9 2021-01-10 B T恤 1010 86 77.27% 24.43% 18.65%
8 2021-01-09 B T恤 1009 63 95.17% 17.90% 18.65%
4 2021-01-05 B T恤 1005 17 100.00% 4.83% 18.65%
26 2021-01-27 B 毛衣 1027 100 32.36% 32.36% 16.38%
23 2021-01-24 B 毛衣 1024 97 63.75% 31.39% 16.38%
22 2021-01-23 B 毛衣 1023 66 85.11% 21.36% 16.38%
21 2021-01-22 B 毛衣 1022 36 96.76% 11.65% 16.38%
27 2021-01-28 B 毛衣 1028 10 100.00% 3.24% 16.38%
20 2021-01-21 B 连衣裙 1021 82 37.44% 37.44% 11.61%
24 2021-01-25 B 连衣裙 1025 72 70.32% 32.88% 11.61%
25 2021-01-26 B 连衣裙 1026 53 94.52% 24.20% 11.61%
19 2021-01-20 B 连衣裙 1020 12 100.00% 5.48% 11.61%

从最终的结果表中,能够清楚的展现出每一笔销售额在组内的占比、累计占比以及本组销售额占总销售额的比例。

以上代码都不复杂,有不理解的地方或者不同意见欢迎留言讨论哦,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值