一、背景介绍:
黑色星期五是美国感恩节后一天,圣诞节前的一次大采购活动,当天一般美国商场会推出大量的打折优惠、促销活动。商家期望通过以这一天开始的圣诞大采购为这一年获得最多的盈利。
二、分析目的:
本次的分析数据来自于Kaggle提供的某电商黑色星期五的销售记录, 将围绕产品和用户两大方面展开叙述,为电商平台制定策略提供分析及建议。
三、主要分析框架
四、分析过程
准备工作:BlackFriday.csv 数据集,分析工具:Anaconda Jupyter Notebook
导入数据集及包,数据集内容如下
==数据集内容==
User_ID:用户ID
Product_ID:产品ID
Gender:性别
Age:年龄
Occupation:职业
City_Category:城市(A,B,C)
Stay_In_Current_City_Years:居住时长
Marital_Status:婚姻状况
Product_Category_1:产品类别1,是一级分类
Product_Category_2:产品类别2,是二级分类
Product_Category_3:产品类别3,是三级分类
Purchase:金额(美元)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
df=pd.read_csv("BlackFriday.csv")
查看数据情况
df.info()
out:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 537577 entries, 0 to 537576
Data columns (total 13 columns):
User_ID 537577 non-null int64
Product_ID 537577 non-null object
Gender 537577 non-null object
Age 537577 non-null object
Occupation 537577 non-null int64
City_Category 537577 non-null object
Stay_In_Current_City_Years 537577 non-null object
Marital_Status 537577 non-null int64
Product_Category_1 537577 non-null int64
Product_Category_2 370591 non-null float64
Product_Category_3 164278 non-null float64
Purchase 537577 non-null int64
Gender_MaritalStatus 537577 non-null object
dtypes: float64(2), int64(5), object(6)
memory usage: 53.3+ MB
通过查看数据,发现Product_Category_2与Product_Category_3缺失数据较多。
1. 整体消费情况分析
1)总消费金额
df['Purchase'].sum()
2)产品销量
df['Product_ID'].count()
3)产品平均单价
(df['Purchase'].sum() / df['Product_ID'].count())
4)客单价
df['Purchase'].sum() / df['User_ID'].nunique()
out:
5017668378 # 总消费金额
537577 # 总销量
9333.8598526350652 # 产品平均单价
851751.5494822611 # 客单价
从整体消费来看,总消费金额为50亿美金,人均消费金额高达85万美元。
2. 客户消费情况分析
1)不同性别的消费金额,消费数量及平均消费额情况
# 对性别分类,求个性别消费金额【1】及各性别人数【2】
df_gender_purchase=df.groupby("Gender").agg({"Purchase":"sum","User_ID":pd.Series.nunique}).reset_index().rename(columns={"Purchase":"Purchase_amount","User_ID":"gender_user_count"})
# 计算各性别的消费金额占比【3】
df_gender_purchase["gender_purchase_prop"]=df_gender_purchase.apply(lambda x:x[1]/df["Purchase"].sum(),axis=1)
# 金额/人数,男女性别分别人均消费【4】
df_gender_purchase["gender_customer_price"]=df_gender_purchase.apply(lambda x:x[1]/x[2],axis=1)
# 男女人数/总人数求得男女人数的占比【5】
df_gender_purchase["gender_count_prop"]=df_gender_purchase.apply(lambda x:x[2]/df["User_ID"].nunique(),axis=1)
df_gender_purchase
在黑色星期五的活动中,男性是占据了71%的用户,贡献了将近76%的销售额,且客单价还是较高于女性,可重点针对男性进行推销
2)不同年龄段的消费金额,消费数量及平均消费额情况
# 根据age分组,求各年龄段的消费金额【1】及各年龄段人数【2】
df_age_purchase=df.groupby("Age").agg({"Purchase":"sum","User_ID":pd.Series.nunique}).reset_index().rename(columns={"Purchase":"Purchase_amount","User_ID":"Age_user_count"})
# 各年龄阶段的消费金额 / 总消费金额,求得各年龄段的消费金额占比【3】
df_age_purchase["Age_purchase_prop"]=df_age_purchase.apply(lambda x:x[1]/df["Purchase"].sum(),axis=1)
# 用各年龄段的消费金额 / 各年龄段的人数,求得各年龄段的人均消费【4】
df_age_purchase["Age_customer_price"]=df_age_purchase.apply(lambda x:x[1]/x[2],axis=1)
# 各年龄段人数 / 总人数 求得各年龄段人数占比【5】
df_age_purchase["Age_count_prop"]=df_age_purchase.apply(lambda x:x[2]/df["User_ID"].nunique(),axis=1)
df_age_purchase
消费人数和金额主要集中在18-45这个年龄阶段,贡献了近80%的销售额及70%+的销售量,其中26-35年龄段是消费的主力军。后续商品推销重点要放在18-45岁年龄段的用户。
3)不同职业的消费金额,消费数量及平均消费额情况
# 对职业分组,求不同职业的消费总额,以及人数【1】【2】
df_Occupation_purchase=df.groupby("Occupation").agg({"Purchase":"sum","User_ID":pd.Series.nunique}).reset_index().rename(columns={"Purchase":"Purchase_amount","User_ID":"Occupation_user_count"})
# 职业别消费总额 / 销售总额,求得各职业的消费额占比【3】
df_Occupation_purchase["Occupation_purchase_prop"]=df_Occupation_purchase.apply(lambda x:x[1]/df["Purchase"].sum(),axis=1)
# 职业消费总额 / 职业消费人数,求得职业人均消费【4】
df_Occupation_purchase["Occupation_customer_price"]=df_Occupation_purchase.apply(lambda x:x[1]/x[2],axis=1)
# 职业的消费人数 / 总消费人数,求得职业消费人数占比
df_Occupation_purchase["Occupation_count_prop"]=df_Occupation_purchase.apply(lambda x:x[2]/df["User_ID"].nunique(),axis=1)
# 根据职业消费人数进行倒序排列
df_Occupation_purchase.sort_values(by="Occupation_user_count",ascending=False)
销量前20%的职业为“4”,“0”,“7”,“1”,这四类职业贡献了约45%的销量及销售额。这些职业是后续重点关注的对象
4)不同婚姻状态的消费金额,消费数量及平均消费额情况
# 对结婚情况分类,求个状态的消费金额【1】及个状态人数【2】
df_Marital_purchase=df.groupby("Marital_Status").agg({"Purchase":"sum","User_ID":pd.Series.nunique}).reset_index().rename(columns={"Purchase":"Purchase_amount","User_ID":"Marital_user_count"})
# 用个状态消费金额 / 总消费金额,求得个状态的消费占比【3】
df_Marital_purchase["Marital_purchase_prop"]=df_Marital_purchase.apply(lambda x:x[1]/df["Purchase"].sum(),axis=1)
# 各状态消费金额/个状态人数,求得各状态人均消费情况【4】
df_Marital_purchase["Marital_customer_price"]=df_Marital_purchase.apply(lambda x:x[1]/x[2],axis=1)
# 各状态人数 / 总人数,求得个状态人数占比【5】
df_Marital_purchase["Marital_count_prop"]=df_Marital_purchase.apply(lambda x:x[2]/df["User_ID"].nunique(),axis=1)
df_Marital_purchase
未结婚的人贡献销售额及销量均比结婚后的人贡献的高约20%
5)不同城市的消费金额,消费数量及平均消费额情况
# 对城市进行分组,求消费金额的聚合【1】各城市总金额【2】各城市客户数
df_City_Category_purchase=df.groupby("City_Category").agg({"Purchase":"sum","User_ID":pd.Series.nunique}).reset_index().rename(columns={"Purchase":"Purchase_amount","User_ID":"City_Category_user_count"})
# 各城市总金额 / 总金额,求得个城市消费金额的占比【3】
df_City_Category_purchase["Marital_purchase_prop"]=df_City_Category_purchase.apply(lambda x:x[1]/df["Purchase"].sum(),axis=1)
# 各城市总金额 / 各城市客户数,求得个城市人均消费【4】
df_City_Category_purchase["City_Category_customer_price"]=df_City_Category_purchase.apply(lambda x:x[1]/x[2],axis=1)
# 个城市客户数 / 总客户数,求得个城市客户数占比
df_City_Category_purchase["City_Category_count_prop"]=df_City_Category_purchase.apply(lambda x:x[2]/df['User_ID'].nunique(),axis=1)
df_City_Category_purchase
C 城市的销量占总销量53%,但是所贡献销售额仅仅占了30%;
B 城市的销量占总销量28%确贡献了近40%的销售额;
AB 城市的客单价是分别是C城市的近2倍。
可知AB城市的消费水品较高,后续可尝试对AB城市的价格适当提高,进一步提升销售额;C城市可以适当降低价格,提高销售量来提高销售额。
3. 产品销售情况分析
1)销售额Top10的产品情况
# 根据产品分组,求各产品被购买的次数,销售总额,同时根据销售总额降序排列,选取Top10,只选取"Product_ID","Purchase_amount"两列,
df_amount10=df.groupby("Product_ID").agg({"User_ID":"count","Purchase":"sum"}).rename(columns={"Purchase":"Purchase_amount","User_ID":"User_count"}).reset_index().sort_values(by=["Purchase_amount"],ascending=False)[["Product_ID","Purchase_amount"]].head(10)
df_amount10
2)销量Top10的产品情况
# 根据产品分组,求各产品被购买的次数,销售总额,同时根据销售总额降序排列,选取Top10,只选取"Product_ID","User_count"两列,
df_count10=df.groupby("Product_ID").agg({"User_ID":"count","Purchase":"sum"}).rename(columns={"Purchase":"Purchase_amount","User_ID":"User_count"}).reset_index().sort_values(by=["User_count"],ascending=False)[["Product_ID","User_count"]].head(10)
df_count10
3)销售量&销售额均在Top10的产品情况
# 将销量Top10余销售总额Top10内连接,进而获取销量与销售额都在Top10的产品
pd.merge(df_amount10,df_count10,left_on="Product_ID",right_on="Product_ID",how="inner")
4) 销售额在Last10的产品情况
df_amount_last10=df.groupby("Product_ID").agg({"User_ID":"count","Purchase":"sum"}).rename(columns={"Purchase":"Purchase_amount","User_ID":"User_count"}).reset_index().sort_values(by=["Purchase_amount"],ascending=False)[["Product_ID","Purchase_amount"]].tail(10)
df_amount_last10["Purchase_amount_Prop"] = df_amount_last10.apply(lambda x:x[1]/df["Purchase"].sum(),axis = 1)
df_amount_last10
对于以上10款产品,销售额较少,后续不出售或降低库存
5)产品一级子类销售情况
# 根据产品类别一级分类进行分组,求得各产品的购买数量以及销售总额,并根据Purchase_amount排序,取Top10,只选取"Product_Category_1"子类,与"Purchase_amount"子类总销售金额列
df_amount=df.groupby("Product_Category_1").agg({"User_ID":"count","Purchase":"sum"}).rename(columns={"Purchase":"Purchase_amount","User_ID":"User_count"}).reset_index().sort_values(by=["Purchase_amount"],ascending=False)[["Product_Category_1","Purchase_amount"]]
# 一级分类的销售总额 / 所有产品的销售总额,求得各一级分类的销售额占比
df_amount["Category_Prop"]=df_amount.apply(lambda x:x[1]/df["Purchase"].sum(),axis=1)
df_amount
产品一级子类“1”,“5”,“8”,“6”四个子类的销售额占总销售额近80%,可作为后续重点款,加大推广与备货
结论与建议:
1、用户的角度
结论:职业代号为4、0、7,年龄在26-35岁的未婚男性属于高消费人群,是该电商平台的忠实用户。
建议:
- 重点关注高价值用户,进行更精细化的营销,后续为这些高价值用户提供更多的高价值消费品;
- 针对其他用户,可以多推荐一些热销的爆款产品,引导用户点击购买。
2、产品的角度
结论: - 黑五活动期间,产品类别(一级分类)为1、5、8的产品,销量和销售额都是top3,这3类产品总销量达到75%,贡献了73%的销售额;
- 销售额排名末三位的产品类别为17、12、13,累计贡献的销售额不到0.3%;
- 销量排名末三位的产品类别14、17、19,总销量仅占0.4%左右。
建议: - 对于销售额top10的产品和销售量top10的产品,可利用爆款产品陈列位置为其他产品引流,比如与其他产品做捆绑销售,带动其他产品的销量。最受用户欢迎的产品类别是1、5、8,在这些产品的页面推荐一些其他产品,引导用户去点击购买;
- 还要具体分析下产品类别14、17、19在销量排行榜上位居末三位的原因,如果它们是一些已经淘汰过时的产品,又或者是被替代品占领了市场,可以考虑是否要下架,减少相关渠道的广告等。
3、城市的角度
结论:B城市贡献的销售额最高,而C城市的消费人数最多。
建议: - 最受欢迎的产品类别是1、5、8,仓库管理需按照畅销产品的分类、名单安排库存,对于消费旺盛的B城市提前备货,节省调度;同时监控库存,防止断货。
- 对于C城市,可以开展更大力度的折扣活动,提升销量以增加销售额。