按月求三个重要指标:
在每个维度的总和,或者每个分类的环比、同比。
一家国外品牌的自行车生产公司,在中国拥有三个代理商帮助销售其品牌产品,该品牌的自行在中国车十分畅销,在各个地区都有其用户。
该场景下的维度有:
以月为单位就算,计算各维度中某分类的总和、同比、环比
Dataframe里每一行代表一位客人在某一天购买的一辆单车。
有83285条的订单记录,26列
df.shape
#(83285, 26)
df.info()
'''
Int64Index: 83285 entries, 0 to 83342
Data columns (total 26 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 创建日期 83285 non-null object
1 创建年月 83285 non-null object
2 季度 83285 non-null int64
3 一年的周数 83285 non-null int64
4 星期 83285 non-null int64
5 当月的天数 83285 non-null int64
6 两年的周数 83285 non-null int64
7 是否今天 83285 non-null int64
8 订单ID 83285 non-null float64
9 客户ID 83285 non-null int64
10 商品ID 83285 non-null object
11 商品名 83285 non-null object
12 商品子类 83285 non-null object
13 商品类别 83285 non-null object
14 价格 83285 non-null float64
15 客户创建日期 83285 non-null object
16 出生日期 83285 non-null object
17 性别 83285 non-null object
18 婚否 83285 non-null object
19 年收入 83285 non-null float64
20 省 83285 non-null object
21 市 83285 non-null object
22 地区 83285 non-null object
23 代理商 83285 non-null object
24 成本 83285 non-null float64
25 渠道 83285 non-null object
dtypes: float64(4), int64(7), object(15)
memory usage: 17.2+ MB
'''
时间是从2019年1月2日到2020年9月30日
df['创建日期'].value_counts().sort_index()
'''
2019-01-02 85
2019-01-03 104
2019-01-04 98
2019-01-05 101
2019-01-06 84
...
2020-09-26 283
2020-09-27 293
2020-09-28 303
2020-09-29 317
2020-09-30 313
Name: 创建日期, Length: 633, dtype: int64
'''
聚合后每个分类的三个指标的总和:
环比:
同比:
以产品维度为例,详细步骤如下:
先观察,查看有多少产品子类
#一共有三个自行车子类:
df['商品子类'].value_counts()
'''
df['商品子类'].value_counts()
公路自行车 44131
山地自行车 27266
旅游自行车 11888
Name: 商品子类, dtype: int64
'''
每个子类在每个月的销售表现
#算出了每个分类在每个月的总客户数、销量、销售额
product_category=df.groupby(["创建年月","商品子类"]).agg({"客户ID":pd.Series.nunique,"订单ID":"count","价格":"sum"}).reset_index()
product_category=product_category.rename(columns={"客户ID":"客户数","订单ID":"销量","价格":"销售额"})
计算环比
先到pivot_table()转化行列
pivot_table()跟Excel的透视表功能一致,能对所需字段进行求和、求平均等。注意values一定要是数值类型,否则不能计算。
pivot_table()官方链接
category_diff=product_category.pivot_table(index=["创建年月"],columns=["商品子类"],values=["客户数","销量","销售额"])
pct_change()算环比
pct_change()的能计算变化率,即(后一个值-前一个值)/前一个值,这里因为行引索是按[年-月]顺序,所以能直接用于求环比。
pct_change()官网链接
category_diff=category_diff.pct_change()
category_diff
由上图可以看到pivot_table()后创建了多层列引索,
#代码查看列引索:
category_diff.columns
'''
MultiIndex([('客户数', '公路自行车'),
('客户数', '山地自行车'),
('客户数', '旅游自行车'),
('销售额', '公路自行车'),
('销售额', '山地自行车'),
('销售额', '旅游自行车'),
( '销量', '公路自行车'),
( '销量', '山地自行车'),
( '销量', '旅游自行车')],
names=[None, '商品子类'])
'''
stack()进行处理。
stack的英文意思就是“堆叠”。stack()能将dataframe的列变成行。
#把子类从列转成行
category_diff=category_diff.stack()
category_diff
#代码查看行引索:
category_diff.index
'''
MultiIndex([('2019-02', '公路自行车'),
('2019-02', '山地自行车'),
('2019-02', '旅游自行车'),
('2019-03', '公路自行车'),
('2019-03', '山地自行车'),
('2019-03', '旅游自行车'),
('2019-04', '公路自行车'),
('2019-04', '山地自行车'),
......
('2020-08', '公路自行车'),
('2020-08', '山地自行车'),
('2020-08', '旅游自行车'),
('2020-09', '公路自行车'),
('2020-09', '山地自行车'),
('2020-09', '旅游自行车')],
names=['创建年月', '商品子类'])
'''
再用reset_index()去处理
reset_index()给Dataframe的行引索重新排序,把原本的行引索都变成了字段,变成值。
category_diff=category_diff.reset_index()
category_diff
接着rename()字段
rename()改一下字段名,改成指标环比
category_diff=category_diff.rename(columns={"客户数":"客户数环比","销售额":"销售额环比","销量":"销量环比"})
最后merge()组合两个表
product_category=product_category.merge(category_diff,how="left",on=["创建年月","商品子类"])
product_category
计算同比
同比一般情况下是今年第n月与去年第n月比。
同比发展速度主要是为了消除季节变动的影响,用以说明本期发展水平与去年同期发展水平对比而达到的相对发展速度。
举例:
2020年1月销量同比=(2020年1月销量-2019年1月销量)/2019年1月销量
先提取月份:
product_category["月"]=product_category["创建年月"].apply(lambda x:x.split("-")[1])
用for loop分两层算同比:
customers_diff=pd.Series([])
orders_diff=pd.Series([])
amount_diff=pd.Series([])
for month in month_values:
for zi_lei in zi_lei_list:
customers_change=pd.Series([])
customers_change=product_category[(product_category["月"]==month)&(product_category["商品子类"]==zi_lei)]["客户数"].pct_change()
customers_diff=customers_diff.append(customers_change)
orders_change=pd.Series([])
orders_change=product_category[(product_category["月"]==month)&(product_category["商品子类"]==zi_lei)]["销量"].pct_change()
orders_diff=orders_diff.append(orders_change)
amount_change=pd.Series([])
amount_change=product_category[(product_category["月"]==month)&(product_category["商品子类"]==zi_lei)]["销售额"].pct_change()
amount_diff=amount_diff.append(amount_change)
product_category["客户数同比"]=customers_diff
product_category["订单数同比"]=orders_diff
product_category["总价同比"]=amount_diff
product_category
再举一个例子,算每个代理商的销售表现,即每个月的客户数、销量、销售额以及对应的环比、同比。
df["代理商"].value_counts()
'''
天逸 38774
悦扬 22697
爱动体育 21814
Name: 代理商, dtype: int64
'''
整体
dist_performent=df.groupby(["创建年月","代理商"]).agg({"客户ID":pd.Series.nunique,"订单ID":"count","价格":"sum"}).reset_index()
dist_performent=dist_performent.rename(columns={"客户ID":"客户数","订单ID":"销量","价格":"销售额"})
dist_performent
环比
dist_performent_diff=dist_performent.pivot_table(index=["创建年月"],columns=["代理商"],values=["客户数","销量","销售额"])
dist_performent_diff=dist_performent_diff.pct_change().stack().reset_index().rename(columns={"客户数":"客户数环比","销售额":"销售额环比","销量":"销量环比"})
dist_performent=dist_performent.merge(dist_performent_diff,how="left",on=["创建年月","代理商"])
dist_performent
同比
dist_performent["月"]=dist_performent["创建年月"].apply(lambda x:x.split("-")[1])
month_values=dist_performent["月"].unique().tolist()
dist_list=dist_performent["代理商"].unique().tolist()
customers_diff=pd.Series([])
orders_diff=pd.Series([])
amount_diff=pd.Series([])
for month in month_values:
for dist in dist_list:
customers_change=pd.Series([])
customers_change=dist_performent[(dist_performent["月"]==month)&(dist_performent["代理商"]==dist)]["客户数"].pct_change()
customers_diff=customers_diff.append(customers_change)
orders_change=pd.Series([])
orders_change=dist_performent[(dist_performent["月"]==month)&(dist_performent["代理商"]==dist)]["销量"].pct_change()
orders_diff=orders_diff.append(orders_change)
amount_change=pd.Series([])
amount_change=dist_performent[(dist_performent["月"]==month)&(dist_performent["代理商"]==dist)]["销售额"].pct_change()
amount_diff=amount_diff.append(amount_change)
dist_performent["客户数同比"]=customers_diff
dist_performent["销量同比"]=orders_diff
dist_performent["销售额同比"]=amount_diff
dist_performent