黑五销售分析

别说谁变了你拦得住时间么 提交于 2019-11-27 09:55:31

利用黑五销售统计数据,分析用户特征、商品销售情况、主力消费人群和用户偏好商品四个方面内容。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
sns.set_style("ticks")#设置绘图风格
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题

1 数据总览

black_friday=pd.read_csv('BlackFriday.csv')
black_friday.head()
User_ID Product_ID Gender Age Occupation City_Category Stay_In_Current_City_Years Marital_Status Product_Category_1 Product_Category_2 Product_Category_3 Purchase
0 1000001 P00069042 F 0-17 10 A 2 0 3 NaN NaN 8370
1 1000001 P00248942 F 0-17 10 A 2 0 1 6.0 14.0 15200
2 1000001 P00087842 F 0-17 10 A 2 0 12 NaN NaN 1422
3 1000001 P00085442 F 0-17 10 A 2 0 12 14.0 NaN 1057
4 1000002 P00285442 M 55+ 16 C 4+ 0 8 NaN NaN 7969
black_friday.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 537577 entries, 0 to 537576
Data columns (total 12 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
dtypes: float64(2), int64(5), object(5)
memory usage: 49.2+ MB

数据共有537577行,12列。

各列说明如下:

  • User_ID:用户ID
  • Product_ID:商品ID
  • Gender:性别,M为男性,F为女性
  • Age:年龄段,划分为0-17、18-25、26-35、36-45、46-55、55+共六个年龄段
  • Occupation:职业,已转换为数字标签,共有21类职业
  • City_Category:所在城市类别,转换为字母标签,分为A、B、C三类
  • Stay_In_Current_City_Years:所在城市居住年份,分为0、1、2、3、4+五个类别
  • Marital_Status:婚姻状况,0为未婚,1为已婚
  • Product_Category_1:商品标签1,已转换为数字标签,范围1-18
  • Product_Category_2:商品标签2,已转换为数字标签,范围2-18
  • Product_Category_3:商品标签3,已转换为数字标签,范围3-18
  • Purchase:消费金额,单位为美元

2 定义一些画图的函数

def pie(data=None,title=None,length=6,height=6,dpi=100):
    '''绘制饼图的函数'''
    fig,ax=plt.subplots(figsize=(length,height),dpi=dpi)
    size=0.5
    labels=data.index
    ax.pie(data,labels=labels,
       startangle=90,autopct='%.1f%%',colors=sns.color_palette("husl",len(data)),
       radius=1,#控制饼图半径,默认为1
       pctdistance=0.75,#控制百分比显示位置
       wedgeprops=dict(width=size,edgecolor='w'),#控制甜甜圈的宽度,边缘颜色等
       textprops=dict(fontsize=10)#控制字号及颜色等
      )
    ax.set_title(title,fontsize=15)
def bar(data=None,title=None,width=0.6,length=10,height=6,dpi=100,text_distance=10,text_fontsize=10,):
    '''绘制柱状图的函数'''
    fig,ax=plt.subplots(figsize=(length,height),dpi=dpi)
    x=np.arange(len(data))
    y=data.values
    labels=data.index
    width=width
    ax.bar(x,y,width=width,color=sns.color_palette("Set2",1))
    ax.set_xticks([i for i in range(len(data))])
    ax.set_xticklabels(labels)
    ax.set_title(title,fontsize=18)
    for a,b in enumerate(y):
        ax.text(a,b+text_distance,b,ha='center',fontsize=text_fontsize)
def user_analyse_bar(data=None,title=None,n=2,length=10,height=6,dpi=100,total_width=0.6,text_fontsize=10,text_distance=10):
    '''
    用于绘制用户特征细分的柱状图
    '''
    fig,ax=plt.subplots(figsize=(length,height),dpi=dpi)
    data_m=data.loc['M']
    data_f=data.loc['F']
    total_width=total_width
    n=n
    width=total_width/n
    x=np.arange(len(data.columns))
    x=x-(total_width-width)/2
    xlabel=data.columns
    ax.bar(x,data_m,width=width,label='Male',color='#36ADA4')
    ax.bar(x+width,data_f,width=width,label='Female',color='#F77189')
    ax.set_xticks(np.linspace(0,len(data.columns)-1,len(data.columns)))
    ax.set_xticklabels(xlabel)
    for x,y1,y2 in zip(x,data_m,data_f):
        ax.text(x,y1+text_distance,y1,ha='center',fontsize=text_fontsize)
        ax.text(x+width,y2+text_distance,y2,ha='center',fontsize=text_fontsize)
    ax.set_title(title,fontsize=18)
    ax.legend()

3 用户是一些什么人?

#提取用户数据并去重
user=black_friday.loc[:,'User_ID':'Marital_Status'].drop_duplicates(subset='User_ID')
user.head()
User_ID Product_ID Gender Age Occupation City_Category Stay_In_Current_City_Years Marital_Status
0 1000001 P00069042 F 0-17 10 A 2 0
4 1000002 P00285442 M 55+ 16 C 4+ 0
5 1000003 P00193542 M 26-35 15 A 3 0
6 1000004 P00184942 M 46-50 7 B 2 1
9 1000005 P00274942 M 26-35 20 A 1 1

3.1 性别

gender=user['Gender'].value_counts().sort_index(ascending=1)
gender_title='黑五购物用户性别比'
pie(gender,gender_title)

在这里插入图片描述

黑五用户以男性为主,占将近四分之三。

3.2 年龄段

age=user['Age'].value_counts().sort_index()
age_title='各年龄段用户人数'
bar(age,age_title)

在这里插入图片描述

3.3 职业

occupation=user['Occupation'].value_counts().sort_values(ascending=False)
occupation_title='各职业用户人数'
bar(occupation,occupation_title,width=0.8,text_distance=5)

在这里插入图片描述

3.4 城市类别

city_category=user['City_Category'].value_counts().sort_index()
city_category
A    1045
B    1707
C    3139
Name: City_Category, dtype: int64
city_category_title='黑五购物用户所在城市'
pie(city_category,city_category_title)

在这里插入图片描述

3.5 居住年份

stay_year=user['Stay_In_Current_City_Years'].value_counts().sort_index()
stay_year_title='黑五购物用户所在城市居住年份'
pie(stay_year,stay_year_title)

在这里插入图片描述

3.6 婚姻状况

marital_status=user['Marital_Status'].value_counts().sort_index()
marital_status.index=['未婚','已婚']
marital_status
未婚    3417
已婚    2474
Name: Marital_Status, dtype: int64
marital_status_title='黑五购物用户婚姻状况'
pie(marital_status,marital_status_title)

在这里插入图片描述

3.7 小结

根据以上分析,可以粗略归纳黑五购物用户的一些特点:

  • 男性居多
  • 年龄以18-45的居多,若缩小年龄段则是26-35
  • 主要职业类别是4、0、7
  • 来自C类城市的用户最多,占比超过一半;其次为B类城市;A类城市最少
  • 居住年份为1年的用户最多,其次为2年的用户,这两类用户占比超过一半
  • 未婚用户略多于已婚用户

4 用户属性交叉分析

从单个属性描述用户特征可能不完善,因此,尝试从多个属性角度进行分析,看用户在不同属性分组下是否有差别。

为避免分析太复杂,这里仅选取部分组合在一起有意义的属性进行两两交叉分析。

4.1 性别-年龄

gender_age=pd.crosstab(user['Gender'],user['Age'])
gender_age
Age 0-17 18-25 26-35 36-45 46-50 51-55 55+
Gender
F 78 287 545 333 182 142 99
M 140 782 1508 834 349 339 273
user_analyse_bar(data=gender_age,title='各年龄段男女用户人数')

在这里插入图片描述

#计算各年龄段的男性比例
gender_age.loc['M']/gender_age.sum(axis=0)
Age
0-17     0.642202
18-25    0.731525
26-35    0.734535
36-45    0.714653
46-50    0.657250
51-55    0.704782
55+      0.733871
dtype: float64

各年龄段都是以男性用户为主,男性占比差异并不十分明显。

4.2 性别-职业

gender_occ=pd.crosstab(user['Gender'],user['Occupation'])
gender_occ.T
Gender F M
Occupation
0 226 462
1 203 314
2 88 168
3 98 72
4 228 512
5 31 80
6 99 129
7 137 532
8 3 14
9 85 3
10 66 126
11 22 106
12 46 330
13 33 107
14 78 216
15 28 112
16 49 186
17 50 441
18 4 63
19 15 56
20 77 196
user_analyse_bar(data=gender_occ,title='各职业男女用户人数',total_width=0.8,length=12,text_fontsize=8,text_distance=2)

在这里插入图片描述

不同职业的男女用户比例差异较大,多数职业男性用户居多,仅有少数职业的女性用户多于男性用户(3、9)。

4.3 性别-城市

gender_city=pd.crosstab(user['Gender'],user['City_Category'])
gender_city
City_Category A B C
Gender
F 295 503 868
M 750 1204 2271
user_analyse_bar(data=gender_city,title='各城市男女用户人数',total_width=0.6,length=6,height=4)

在这里插入图片描述

#计算不同城市的男性比例
gender_city.loc['M']/gender_city.sum(axis=0)
City_Category
A    0.717703
B    0.705331
C    0.723479
dtype: float64

不同城市类别的男女用户比例基本一致。

4.4 性别-婚姻状况

gender_marital=pd.crosstab(user['Gender'],user['Marital_Status'])
gender_marital.rename(columns={0:'未婚',1:'已婚'},inplace=True)
gender_marital
Marital_Status 未婚 已婚
Gender
F 947 719
M 2470 1755
user_analyse_bar(data=gender_marital,title='男女用户婚姻状况',total_width=0.6,length=6,height=4)

在这里插入图片描述

#计算两种婚姻状况下的男性比例
gender_marital.loc['M']/gender_marital.sum(axis=0)
Marital_Status
未婚    0.722856
已婚    0.709378
dtype: float64

不同婚姻状态的男女用户比例基本一致。

4.5 年龄段-城市

age_city=pd.crosstab(user['Age'],user['City_Category'])
age_city
City_Category A B C
Age
0-17 25 50 143
18-25 214 331 524
26-35 461 652 940
36-45 176 335 656
46-50 53 146 332
51-55 67 135 279
55+ 49 58 265
fig,ax=plt.subplots(figsize=(12,6),dpi=100)
data=age_city
data_A=data['A']
data_B=data['B']
data_C=data['C']
total_width=0.8
n=3
width=total_width/n
x=np.arange(len(data))
x=x-(total_width-width)/2
xlabel=data.index
ax.bar(x-width,data_A,width=width,label='A',color='#F77189')
ax.bar(x,data_B,width=width,label='B',color='#80B131')
ax.bar(x+width,data_C,width=width,label='C',color='#3BA3EC')
ax.set_xticks(np.linspace(0,len(data)-1,len(data)))
ax.set_xticklabels(xlabel)
for x,y1,y2,y3 in zip(x,data_A,data_B,data_C):
    ax.text(x-width,y1+2,y1,ha='center',fontsize=8)
    ax.text(x,y2+2,y2,ha='center',fontsize=8)
    ax.text(x+width,y3+2,y3,ha='center',fontsize=8)
ax.set_title('不同年龄段用户的居住城市',fontsize=18)
ax.legend()

在这里插入图片描述

不管在哪个年龄段,都是C类城市的用户最多,B类次之,A类最少。

4.6 年龄段-婚姻状况

age_marital=pd.crosstab(user['Age'],user['Marital_Status'])
age_marital.rename(columns={0:'未婚',1:'已婚'},inplace=1)
age_marital
Marital_Status 未婚 已婚
Age
0-17 218 0
18-25 825 244
26-35 1244 809
36-45 705 462
46-50 156 375
51-55 136 345
55+ 133 239
fig,ax=plt.subplots(figsize=(12,6),dpi=100)
data=age_marital
data_A=data['未婚']
data_B=data['已婚']
total_width=0.8
n=2
width=total_width/n
x=np.arange(len(data))
x=x-(total_width-width)/2
xlabel=data.index
ax.bar(x,data_A,width=width,label=data_A.name,color='#36ADA4')
ax.bar(x+width,data_B,width=width,label=data_B.name,color='#F77189')
ax.set_xticks(np.linspace(0,len(data)-1,len(data)))
ax.set_xticklabels(xlabel)
for x,y1,y2 in zip(x,data_A,data_B):
    ax.text(x,y1+4,y1,ha='center',fontsize=8)
    ax.text(x+width,y2+4,y2,ha='center',fontsize=8)
ax.set_title('不同年龄段用户的婚姻状况',fontsize=18)
ax.legend()

在这里插入图片描述

#计算各年龄段的已婚用户比例
age_marital['已婚']/age_marital.sum(axis=1)
Age
0-17     0.000000
18-25    0.228251
26-35    0.394057
36-45    0.395887
46-50    0.706215
51-55    0.717256
55+      0.642473
dtype: float64

0-17岁均为未婚用户,因为他们没有达到法定婚龄。(美国不同州的法定婚龄不尽相同,但大多为18岁。)

18-25、26-35、36-45这三个年龄段都是未婚用户居多,但已婚用户比例在慢慢增加。

46-50、51-55、55+这三个年龄段都是已婚用户居多,55+年龄段的已婚用户比例较低可能是存在丧偶或离异情况。

4.7 小结

多数交叉分析的结果与单变量分析的结果并无太大差异,在一个属性中占比较大的群体,在与另一个属性进行交叉分析中通常也占较大比例。

职业和婚姻状况存在的较大变动:

  • 不同职业的用户虽然整体上是以男性用户居多,但不同职业的性别比例差异较大
  • 随着年龄的上升,已婚用户的比例逐渐升高,55+年龄段用户的已婚比例虽然有所降低,但仍高于46岁以下用户

5 哪些商品卖得好?

product=black_friday.loc[:,['Product_ID','Product_Category_1','Product_Category_2','Product_Category_3','Purchase']]
print('黑五期间涉及的销售商品共{}个。'.format(len(product['Product_ID'].unique())))
黑五期间涉及的销售商品共3623个。
black_friday.loc[:,['User_ID','Product_ID','Purchase']].sort_values(by='Product_ID').head()
User_ID Product_ID Purchase
519782 1001991 P00000142 11071
320359 1001344 P00000142 10946
320351 1001343 P00000142 13463
339410 1004233 P00000142 8341
104774 1004126 P00000142 13610

可以看出,同一商品对不同用户的销售金额不尽相同,每条记录可能是多个同一商品何必后的结果。以记录数作为商品销量不合理,因此仅对销售额进行统计分析。

5.1 哪些商品的销售额更高

#将销售额按商品ID分类加和后由高到低排列,并计算累计销售额占比
product_purchase=product.loc[:,['Product_ID','Purchase']].groupby('Product_ID').sum().sort_values(by='Purchase',ascending=0).reset_index()
product_purchase['Percent']=product_purchase['Purchase']/product_purchase['Purchase'].sum()
product_purchase['P_Cumsum']=product_purchase['Percent'].cumsum()
product_purchase.head()
Product_ID Purchase Percent P_Cumsum
0 P00025442 27532426 0.005487 0.005487
1 P00110742 26382569 0.005258 0.010745
2 P00255842 24652442 0.004913 0.015658
3 P00184942 24060871 0.004795 0.020453
4 P00059442 23948299 0.004773 0.025226
fig=plt.figure(figsize=(12,6),dpi=100)
ax1=fig.add_subplot(111)
ax1.grid()
ax2=ax1.twinx()#建立副纵坐标轴
data_2=product_purchase['Purchase']
data_1=product_purchase['P_Cumsum']
x=np.arange(1,len(product_purchase)+1)
ax1.plot(x,data_1,color='#ed5a65',label='销售额累计占比')
ax2.plot(x,data_2,color='#5cb3cc',label='单个商品销售额')
ax1.set_xlabel('商品种类')
ax1.set_yticks(np.linspace(0,1,11))
ax1.set_yticklabels(['{:.0%}'.format(i/10) for i in range(11)])#y轴刻度显示百分比
ax1.set_ylabel('累计销售额占比')
ax2.set_ylabel('单个商品的销售额')
ax1.legend(loc=(0.83,0.14))
ax2.legend(loc=(0.83,0.08))
ax1.set_title('黑五各商品销售额的帕累托图',fontsize=18)

在这里插入图片描述

for i in range(1,10):
    percent=i/10
    product_kind=len(product_purchase[product_purchase['P_Cumsum']<=percent])
    product_percent=product_kind/len(product_purchase)
    print("销售额占{:.0%}的商品共有{}种,占销售商品总数的{:.2%}。".format(percent,product_kind,product_percent))
销售额占10%的商品共有23种,占销售商品总数的0.63%。
销售额占20%的商品共有64种,占销售商品总数的1.77%。
销售额占30%的商品共有124种,占销售商品总数的3.42%。
销售额占40%的商品共有206种,占销售商品总数的5.69%。
销售额占50%的商品共有310种,占销售商品总数的8.56%。
销售额占60%的商品共有454种,占销售商品总数的12.53%。
销售额占70%的商品共有647种,占销售商品总数的17.86%。
销售额占80%的商品共有927种,占销售商品总数的25.59%。
销售额占90%的商品共有1400种,占销售商品总数的38.64%。

可以看出,黑五销售额基本符合二八定律,80%的销售额集中在25.59%的商品。

#将销售额占比80%以上的商品作为主要商品
major_product=product_purchase[product_purchase['P_Cumsum']<=0.8]
major_product.head()
Product_ID Purchase Percent P_Cumsum
0 P00025442 27532426 0.005487 0.005487
1 P00110742 26382569 0.005258 0.010745
2 P00255842 24652442 0.004913 0.015658
3 P00184942 24060871 0.004795 0.020453
4 P00059442 23948299 0.004773 0.025226

销售额占比最高的三种商品的ID分别为P00025442、P00110742、P00255842,销售额占比分别为0.55%、0.53%、0.49%。

5.2 哪些类型的商品更畅销

5.2.1 商品标签统计

对销售涉及各商品的商品标签进行分类统计。

对于一个商品有多个商品标签的,对其也按标签进行重复统计。

因此,所有标签统计的加和会大于商品总数。

category_1=pd.DataFrame(product['Product_Category_1'].value_counts().sort_index())
category_2=pd.DataFrame(product['Product_Category_2'].dropna().astype(int).value_counts().sort_index())
category_3=pd.DataFrame(product['Product_Category_3'].dropna().astype(int).value_counts().sort_index())
product_category=pd.merge(category_1,category_2,how='outer',left_index=True,right_index=True)
product_category=pd.merge(product_category,category_3,how='outer',left_index=True,right_index=True)
product_category=product_category.fillna(0).astype(int)
product_category['All']=product_category.sum(axis=1)
product_category
Product_Category_1 Product_Category_2 Product_Category_3 All
1 138353 0 0 138353
2 23499 48481 0 71980
3 19849 2835 600 23284
4 11567 25225 1840 38632
5 148592 25874 16380 190846
6 20164 16251 4818 41233
7 3668 615 0 4283
8 112132 63058 12384 187574
9 404 5591 11414 17409
10 5032 2991 1698 9721
11 23960 13945 1773 39678
12 3875 5419 9094 18388
13 5440 10369 5385 21194
14 1500 54158 18121 73779
15 6203 37317 27611 71131
16 9697 42602 32148 84447
17 567 13130 16449 30146
18 3075 2730 4563 10368
bar(data=product_category['All'].sort_values(ascending=False),title='各标签下的商品数量',text_fontsize=8,text_distance=1500)

在这里插入图片描述

从不同标签的商品数量看,大致可以划分为3大类:

  • 5、8、1为第一集团,商品数量居前三位,但1距离前两名的差距较大
  • 16、14、2、15为第二集团
  • 其他为第三集团

5.2.2 不同标签商品的销售额统计

与不同商品标签下商品数量的统计一样,不同标签商品销售额的统计存在重复统计的问题。这个统计指标可以理解为,带有该标签的商品的总销售额。

cat_1_purchase=product.loc[:,['Product_Category_1','Purchase']].groupby('Product_Category_1').sum().rename(columns=dict(Purchase='Cat_1'))
cat_2_purchase=product.loc[:,['Product_Category_2','Purchase']].groupby('Product_Category_2').sum().rename(columns=dict(Purchase='Cat_2'))
cat_3_purchase=product.loc[:,['Product_Category_3','Purchase']].groupby('Product_Category_3').sum().rename(columns=dict(Purchase='Cat_3'))
cat_purchase=pd.merge(cat_1_purchase,cat_2_purchase,how='outer',left_index=True,right_index=True)
cat_purchase=pd.merge(cat_purchase,cat_3_purchase,how='outer',left_index=True,right_index=True)
cat_purchase=cat_purchase.fillna(0).astype(int)
cat_purchase['All']=cat_purchase.sum(axis=1)
cat_purchase
Cat_1 Cat_2 Cat_3 All
1 1882666325 0 0 1882666325
2 264497242 660395610 0 924892852
3 200412211 31835725 8374300 240622236
4 26937957 257757097 17992055 302687109
5 926917497 233747130 198662402 1359327029
6 319355286 186896021 63548518 569799825
7 60059209 4229499 0 64288708
8 840693394 648112417 161357998 1650163809
9 6277472 40716981 119043392 166037845
10 99029631 46827140 22962030 168818801
11 112203088 124608092 21475687 258286867
12 5235883 37763181 79288332 122287396
13 3931050 100291709 70990467 175213226
14 19718178 384866069 182187903 586772150
15 91658147 386556477 340670945 818885569
16 143168035 438744196 385213413 967125644
17 5758702 123639094 193760503 323158299
18 9149071 25582006 50118090 84849167
bar(data=cat_purchase['All'].sort_values(ascending=False),title='各标签下的商品销售额',text_fontsize=6,text_distance=3000)

在这里插入图片描述

根据不同标签下的商品销售额,大致可以分为4大类:

  • 1、8、5为第一集团,明显高于其他标签商品,但彼此之间的差距也较大
  • 16、2、15为第二集团
  • 14、6为第三集团
  • 其他为第四集团

5.2.3 小结

不同标签的商品数量和销售额的排名基本一致,只是在各集团中的排名略有差异,这应该与商品单价和购买数量有关。

6 哪些用户消费多?

根据用户属性从不同角度分析哪类用户的消费较高。舍弃一些分析意义不大的角度,如居住年份。

6.1 性别

gender_purchase=black_friday.loc[:,['Gender','Purchase']].groupby('Gender').sum()
gender_purchase
Purchase
Gender
F 1164624021
M 3853044357
title='不同性别用户的销售额'
pie(gender_purchase,title)

在这里插入图片描述

#分性别计算人均消费金额
gender_count=pd.DataFrame(black_friday['Gender'].value_counts())
gender_purchase_unit=gender_purchase['Purchase']/gender
fig,ax=plt.subplots(figsize=(8,6))
x=np.arange(len(gender_purchase_unit))
y=gender_purchase_unit.values
ax.bar(x,y,width=0.5,color=sns.color_palette('husl',2))
ax.set_xticks([0,1])
ax.set_xticklabels(['F','M'])
ax.set_ylim(0,1000000)
ax.set_ylabel('人均消费金额(美元)')
ax.set_title('人均消费金额',fontsize=15)
for a,b in enumerate(y):
    ax.text(a,b+10000,'{:.0f}'.format(b),ha='center')

在这里插入图片描述

男性用户在消费总金额和人均消费金额上均高于女性用户。

6.2 年龄段

age_purchase=black_friday.loc[:,['Age','Purchase']].groupby('Age').sum()
age_purchase
Purchase
Age
0-17 132659006
18-25 901669280
26-35 1999749106
36-45 1010649565
46-50 413418223
51-55 361908356
55+ 197614842
pie(age_purchase,title='各年龄段消费金额')

在这里插入图片描述

age_purchase_unit=(age_purchase['Purchase']/age).astype(int)
bar(age_purchase_unit,title='各年龄段人均消费金额',text_distance=10000)

在这里插入图片描述

18-45岁用户是主要消费人群,消费总金额占比接近80%。人均消费金额也高于其他年龄段。

6.3 职业

occ_purchase=black_friday.loc[:,['Occupation','Purchase']].groupby('Occupation').sum()
occ_purchase.head()
Purchase
Occupation
0 625814811
1 414552829
2 233275393
3 160428450
4 657530393
title='各职业的消费金额'
bar(data=occ_purchase.sort_values(by='Purchase',ascending=False)['Purchase'],title=title,length=16,text_fontsize=8.5,text_distance=5000000)

在这里插入图片描述

occ_purchase_unit=occ_purchase['Purchase']/occupation
fig,ax=plt.subplots(figsize=(10,6),dpi=100)
x=np.arange(len(occ_purchase_unit))
y=occ_purchase_unit.sort_values(ascending=False).values
labels=occ_purchase_unit.sort_values(ascending=False).index
width=0.6
ax.bar(x,y,width=width,color=sns.color_palette("Set2",1))
ax.set_xticks([i for i in range(len(occ_purchase_unit))])
ax.set_xticklabels(labels)
ax.set_title('各职业人均消费金额',fontsize=18)

在这里插入图片描述

各职业消费总金额和人均消费金额差别较大:

  • 总消费金额较高的4、0、7三种职业的人均消费金额并不算高,但因其人数较多,所以消费总金额较高
  • 人均消费金额较高的20、19、5、16四种职业的消费总金额不高,说明这些职业的消费能力较高,但消费人数较少
  • 9、10、13三种职业的人均消费金额明显低于其他职业,可能原因较多,包括其本身消费能力较低、对促销商品不感兴趣、不喜欢在促销时段购物等

6.4 城市

city_purchase=black_friday.loc[:,['City_Category','Purchase']].groupby('City_Category').sum()
city_purchase.head()
Purchase
City_Category
A 1295668797
B 2083431612
C 1638567969
pie(city_purchase,title='各类城市消费金额')

在这里插入图片描述

city_purchase_unit=city_purchase['Purchase']/city_category
fig,ax=plt.subplots(figsize=(8,5),dpi=80)
x=np.arange(len(city_purchase_unit))
y=city_purchase_unit.values
labels=city_purchase_unit.index
width=0.6
ax.bar(x,y,width=width,color=sns.color_palette("Set2",1))
ax.set_xticks([i for i in range(len(city_purchase_unit))])
ax.set_xticklabels(labels)
ax.set_title('各类城市人均消费金额',fontsize=18)

在这里插入图片描述

消费总金额是B>C>A,人均消费金额是A>B>C,人数则是C>B>A。据此,有如下推断:

  • B类城市用户是消费主力人群
  • C类城市虽然人数最多,但人均消费能力不足
  • A类城市的消费能力最高,但消费人数最少,可通过加强宣传推广提高消费总金额

6.5 婚姻状况

marital_purchase=black_friday.loc[:,['Marital_Status','Purchase']].groupby('Marital_Status').sum()
marital_purchase.index=['未婚','已婚']
marital_purchase
Purchase
未婚 2966289500
已婚 2051378878
pie(marital_purchase,title='不同婚姻状况用户的消费金额')

在这里插入图片描述

marital_purchase_unit=marital_purchase['Purchase']/marital_status
fig,ax=plt.subplots(figsize=(8,5),dpi=80)
x=np.arange(len(marital_purchase_unit))
y=marital_purchase_unit.values
labels=marital_purchase_unit.index
width=0.6
ax.bar(x,y,width=width,color=sns.color_palette("Set2",1))
ax.set_xticks([i for i in range(len(marital_purchase_unit))])
ax.set_xticklabels(labels)
ax.set_title('不同婚姻状况用户的人均消费金额',fontsize=18)

在这里插入图片描述

已婚用户和未婚用户的人均消费金额差别不大,总消费金额的差异主要由用户数不同引起。

6.6 小结

根据以上分析,黑五消费的主力用户大致有如下特征:

  • 男性
  • 18-45周岁
  • 来自B类城市
  • 职业是4、0或7

除此之外,职业是20、19、5、16的,来自A类城市的用户也具有较大的消费能力,应重点发展。

7 不同用户偏爱什么样的商品

7.1 性别

#分别整理出男女用户购买的商品标签
cat_m=black_friday[black_friday['Gender']=='M'].loc[:,'Product_Category_1':'Product_Category_3']
cat_f=black_friday[black_friday['Gender']=='F'].loc[:,'Product_Category_1':'Product_Category_3']
#统计男用户购买的商品标签
cat_1_m=pd.DataFrame(cat_m['Product_Category_1'].value_counts().sort_index())
cat_2_m=pd.DataFrame(cat_m['Product_Category_2'].dropna().astype(int).value_counts().sort_index())
cat_3_m=pd.DataFrame(cat_m['Product_Category_3'].dropna().astype(int).value_counts().sort_index())
cat_m_sum=pd.merge(cat_1_m,cat_2_m,how='outer',left_index=True,right_index=True)
cat_m_sum=pd.merge(cat_m_sum,cat_3_m,how='outer',left_index=True,right_index=True)
cat_m_sum=cat_m_sum.fillna(0).astype(int)
cat_m_sum['All']=cat_m_sum.sum(axis=1)
cat_m_sum
Product_Category_1 Product_Category_2 Product_Category_3 All
1 113952 0 0 113952
2 17926 39442 0 57368
3 13975 2224 506 16705
4 7995 17774 1412 27181
5 107393 19812 12165 139370
6 15689 13009 4002 32700
7 2740 482 0 3222
8 79185 46842 9489 135516
9 334 4111 8778 13223
10 3894 2273 1287 7454
11 19301 11237 1445 31983
12 2378 3713 6432 12523
13 4012 7750 4173 15935
14 887 34849 12614 48350
15 5180 30989 23080 59249
16 7334 33284 25490 66108
17 506 10689 12778 23973
18 2699 2261 3695 8655
#统计女用户购买的商品标签
cat_1_f=pd.DataFrame(cat_f['Product_Category_1'].value_counts().sort_index())
cat_2_f=pd.DataFrame(cat_f['Product_Category_2'].dropna().astype(int).value_counts().sort_index())
cat_3_f=pd.DataFrame(cat_f['Product_Category_3'].dropna().astype(int).value_counts().sort_index())
cat_f_sum=pd.merge(cat_1_f,cat_2_f,how='outer',left_index=True,right_index=True)
cat_f_sum=pd.merge(cat_f_sum,cat_3_f,how='outer',left_index=True,right_index=True)
cat_f_sum=cat_f_sum.fillna(0).astype(int)
cat_f_sum['All']=cat_f_sum.sum(axis=1)
cat_f_sum
Product_Category_1 Product_Category_2 Product_Category_3 All
1 24401 0 0 24401
2 5573 9039 0 14612
3 5874 611 94 6579
4 3572 7451 428 11451
5 41199 6062 4215 51476
6 4475 3242 816 8533
7 928 133 0 1061
8 32947 16216 2895 52058
9 70 1480 2636 4186
10 1138 718 411 2267
11 4659 2708 328 7695
12 1497 1706 2662 5865
13 1428 2619 1212 5259
14 613 19309 5507 25429
15 1023 6328 4531 11882
16 2363 9318 6658 18339
17 61 2441 3671 6173
18 376 469 868 1713
#合并男女用户购买的商品标签数
cat_gender_sum=pd.DataFrame(cat_m_sum['All']).rename(columns=dict(All='M')).join(pd.DataFrame(cat_f_sum['All']).rename(columns=dict(All='F')))
fig=plt.figure(figsize=(12,6),dpi=100)
ax1=fig.add_subplot(1,2,1)
ax1.pie(cat_gender_sum['M'].sort_values(ascending=False),labels=cat_gender_sum['M'].sort_values(ascending=False).index,shadow=True,
       startangle=90,colors=sns.color_palette('husl',18),
       textprops=dict(fontsize=9))
ax1.axis('equal')
ax1.set_title('男性用户购买商品的标签数量',fontsize=15)
ax2=fig.add_subplot(1,2,2)
ax2.pie(cat_gender_sum['F'].sort_values(ascending=False),labels=cat_gender_sum['F'].sort_values(ascending=False).index,shadow=True,
       startangle=90,colors=sns.color_palette('husl',18),
       textprops=dict(fontsize=9))
ax2.axis('equal')
ax2.set_title('女性用户购买商品的标签数量',fontsize=15)

在这里插入图片描述

7.2 城市类别

#分别整理出各类城市用户购买的商品标签
cat_A=black_friday[black_friday['City_Category']=='A'].loc[:,'Product_Category_1':'Product_Category_3']
cat_B=black_friday[black_friday['City_Category']=='B'].loc[:,'Product_Category_1':'Product_Category_3']
cat_C=black_friday[black_friday['City_Category']=='C'].loc[:,'Product_Category_1':'Product_Category_3']

#统计A类城市用户购买的商品标签
cat_1_A=pd.DataFrame(cat_A['Product_Category_1'].value_counts().sort_index())
cat_2_A=pd.DataFrame(cat_A['Product_Category_2'].dropna().astype(int).value_counts().sort_index())
cat_3_A=pd.DataFrame(cat_A['Product_Category_3'].dropna().astype(int).value_counts().sort_index())
cat_A_sum=pd.merge(cat_1_A,cat_2_A,how='outer',left_index=True,right_index=True)
cat_A_sum=pd.merge(cat_A_sum,cat_3_A,how='outer',left_index=True,right_index=True)
cat_A_sum=cat_A_sum.fillna(0).astype(int)
cat_A_sum['All']=cat_A_sum.sum(axis=1)

#统计B类城市用户购买的商品标签
cat_1_B=pd.DataFrame(cat_B['Product_Category_1'].value_counts().sort_index())
cat_2_B=pd.DataFrame(cat_B['Product_Category_2'].dropna().astype(int).value_counts().sort_index())
cat_3_B=pd.DataFrame(cat_B['Product_Category_3'].dropna().astype(int).value_counts().sort_index())
cat_B_sum=pd.merge(cat_1_B,cat_2_B,how='outer',left_index=True,right_index=True)
cat_B_sum=pd.merge(cat_B_sum,cat_3_B,how='outer',left_index=True,right_index=True)
cat_B_sum=cat_B_sum.fillna(0).astype(int)
cat_B_sum['All']=cat_B_sum.sum(axis=1)

#统计C类城市用户购买的商品标签
cat_1_C=pd.DataFrame(cat_C['Product_Category_1'].value_counts().sort_index())
cat_2_C=pd.DataFrame(cat_C['Product_Category_2'].dropna().astype(int).value_counts().sort_index())
cat_3_C=pd.DataFrame(cat_C['Product_Category_3'].dropna().astype(int).value_counts().sort_index())
cat_C_sum=pd.merge(cat_1_C,cat_2_C,how='outer',left_index=True,right_index=True)
cat_C_sum=pd.merge(cat_C_sum,cat_3_C,how='outer',left_index=True,right_index=True)
cat_C_sum=cat_C_sum.fillna(0).astype(int)
cat_C_sum['All']=cat_C_sum.sum(axis=1)

#合并各类城市用户购买的商品标签数
cat_city_sum=pd.DataFrame(cat_A_sum['All']).rename(columns=dict(All='A')).join(pd.DataFrame(cat_B_sum['All']).rename(columns=dict(All='B')))
cat_city_sum=cat_city_sum.join(pd.DataFrame(cat_C_sum['All']).rename(columns=dict(All='C')))
fig=plt.figure(figsize=(12,6),dpi=100)
ax1=fig.add_subplot(1,3,1)
ax1.pie(cat_city_sum['A'].sort_values(ascending=False),labels=cat_city_sum['A'].sort_values(ascending=False).index,shadow=True,
       startangle=90,colors=sns.color_palette('husl',18),
       textprops=dict(fontsize=7))
ax1.axis('equal')
ax1.set_title('A类城市用户购买商品的标签数量',fontsize=13)

ax2=fig.add_subplot(1,3,2)
ax2.pie(cat_city_sum['B'].sort_values(ascending=False),labels=cat_city_sum['B'].sort_values(ascending=False).index,shadow=True,
       startangle=90,colors=sns.color_palette('husl',18),
       textprops=dict(fontsize=7))
ax2.axis('equal')
ax2.set_title('B类城市用户购买商品的标签数量',fontsize=13)

ax3=fig.add_subplot(1,3,3)
ax3.pie(cat_city_sum['C'].sort_values(ascending=False),labels=cat_city_sum['C'].sort_values(ascending=False).index,shadow=True,
       startangle=90,colors=sns.color_palette('husl',18),
       textprops=dict(fontsize=7))
ax3.axis('equal')
ax3.set_title('C类城市用户购买商品的标签数量',fontsize=13)

在这里插入图片描述

7.3 婚姻状况

#分别整理出已婚、未婚用户购买的商品标签
cat_0=black_friday[black_friday['Marital_Status']==0].loc[:,'Product_Category_1':'Product_Category_3']
cat_1=black_friday[black_friday['Marital_Status']==1].loc[:,'Product_Category_1':'Product_Category_3']

#统计未婚用户购买的商品标签
cat_1_0=pd.DataFrame(cat_0['Product_Category_1'].value_counts().sort_index())
cat_2_0=pd.DataFrame(cat_0['Product_Category_2'].dropna().astype(int).value_counts().sort_index())
cat_3_0=pd.DataFrame(cat_0['Product_Category_3'].dropna().astype(int).value_counts().sort_index())
cat_0_sum=pd.merge(cat_1_0,cat_2_0,how='outer',left_index=True,right_index=True)
cat_0_sum=pd.merge(cat_0_sum,cat_3_0,how='outer',left_index=True,right_index=True)
cat_0_sum=cat_0_sum.fillna(0).astype(int)
cat_0_sum['All']=cat_0_sum.sum(axis=1)

#统计已婚用户购买的商品标签
cat_1_1=pd.DataFrame(cat_1['Product_Category_1'].value_counts().sort_index())
cat_2_1=pd.DataFrame(cat_1['Product_Category_2'].dropna().astype(int).value_counts().sort_index())
cat_3_1=pd.DataFrame(cat_1['Product_Category_3'].dropna().astype(int).value_counts().sort_index())
cat_1_sum=pd.merge(cat_1_1,cat_2_1,how='outer',left_index=True,right_index=True)
cat_1_sum=pd.merge(cat_1_sum,cat_3_1,how='outer',left_index=True,right_index=True)
cat_1_sum=cat_1_sum.fillna(0).astype(int)
cat_1_sum['All']=cat_1_sum.sum(axis=1)

#合并已婚未婚用户购买的商品标签数
cat_marital_sum=pd.DataFrame(cat_0_sum['All']).rename(columns=dict(All='未婚')).join(pd.DataFrame(cat_1_sum['All']).rename(columns=dict(All='已婚')))
fig=plt.figure(figsize=(12,6),dpi=100)
ax1=fig.add_subplot(1,2,1)
ax1.pie(cat_marital_sum['未婚'].sort_values(ascending=False),labels=cat_marital_sum['未婚'].sort_values(ascending=False).index,shadow=True,
       startangle=90,colors=sns.color_palette('husl',18),
       textprops=dict(fontsize=9))
ax1.axis('equal')
ax1.set_title('未婚用户购买商品的标签数量',fontsize=15)
ax2=fig.add_subplot(1,2,2)
ax2.pie(cat_marital_sum['已婚'].sort_values(ascending=False),labels=cat_marital_sum['已婚'].sort_values(ascending=False).index,shadow=True,
       startangle=90,colors=sns.color_palette('husl',18),
       textprops=dict(fontsize=9))
ax2.axis('equal')
ax2.set_title('已婚用户购买商品的标签数量',fontsize=15)

在这里插入图片描述

小结

总的来说,从性别、城市类别、婚姻状况三个角度划分用户并分析其购买商品的偏好,发现不同用户群体的偏好差异不大。

仅有男女用户对标签1和14的商品偏好稍大。相比之下,男性用户对于1类商品更为青睐,女性用户对这两种商品的偏好并没有太大差异。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!