日本超级商场数据分析

import os
import pandas as pd
import matplotlib.pyplot as plt    # 绘图库
import numpy as np
plt.rcParams['font.sans-serif'] = ['SimHei']#设置中文字体为黑体
%matplotlib inline
plt.rcParams['axes.unicode_minus'] = False #正常显示负号
plt.style.use('ggplot')
data = pd.read_csv('サンプル - スーパーストア.csv',encoding='UTF-8')
data.info()
#删除重复记录
data.drop_duplicates(keep='first',inplace=True)
#删除缺失值(na,删除带有na的整行数据,axis=0,how=‘any’默认值)
data.dropna(axis=0,how='any',inplace=True)
data.drop(columns=['行 ID'],inplace=True,axis=1)
print(data.info())

data['オーダー日'] = pd.to_datetime(data['オーダー日'])
data['月'] = data['オーダー日'].apply(lambda x:x.month)
data
#割引率==0,采用删除方法,因为数据量很小
data = data[data['割引率'] !=0]
data.describe()

#送货方式维度分析
data['出荷日'] = data['出荷モード'].str.strip()
data1 = data.groupby(['月','出荷モード']).size().unstack()
data1
#购买范围前15个
サブカテゴリ_count = data['サブカテゴリ'].value_counts()[:15]
print(サブカテゴリ_count)
サブカテゴリ_count.plot(kind='line',color=['r'])
サブカテゴリ_count.plot(kind='bar',fontsize=16)
for x,y in enumerate(サブカテゴリ_count):
    print(x,y)
    plt.text(x,y+2,y,ha='center',fontsize=12)

 

#绘制顧客区分占比 (饼图)
pin_tai = data[['顧客区分','売上']].groupby('顧客区分').agg(売上 = ('売上','sum'))
#我们按照顧客区分进行分组,对顧客区分进行聚合
pin_tai = pd.Series(pin_tai.売上,index=pin_tai.index)
#将DataFrame类型转换为Series类型
plt.pie(pin_tai,autopct='%2.1f%%',labels=['大企業','小規模事業所','消費者'])
#调用pie方法,传入数据pin_tai;autopct:数据标签;%2.1f 输出宽度为2的浮点数,小数点宽度为1;labels 为标签

 

#绘制出利益率
data.オーダー日 = pd.to_datetime(data.オーダー日)
#先对日期格式转换为datetime64格式,方便我们对日期进行采样操作
data['利益率'] = data.利益/data.売上
#data2['进店率'] = data2.进店人数/data2.曝光人数
#创建字段:利益率
利益_rates = data.groupby(data.オーダー日).agg(売上总和 = ('売上','sum'),利益总和 = ('利益','sum'),利益率 = ('利益率','sum')).resample('3M').asfreq().dropna(how = 'any')
利益_rates

 ​​

plt.plot(利益_rates.index, 利益_rates.利益率,label = '利益率')
#plt.plot(利益_rates.index, gmv_rates.下单率,label = '下单率')
plt.legend()

for a,b in zip(利益_rates.index, 利益_rates.利益率):
    plt.text(a,b+0.01,'%.2f'%b,ha='center',va='bottom',fontsize=16)
#for a,b in zip(gmv_rates.index, gmv_rates.下单率):
    plt.text(a,b+0.01,'%.2f'%b,ha='center',va='bottom',fontsize=16)
plt.xticks(rotation=-15)

#是否存在尚有潜力的销售区域
data1 = data.groupby(['月','カテゴリ'])['数量'].sum().unstack()
data1.plot(kind='line')
#事务用品卖的最好
#5月所有商品类型都卖得很好

#从销售区域看,关东货品卖的最好,四国卖的最差
data1 = data.groupby(['地域','カテゴリ'])['数量'].sum().unstack()
data1

data1 = data.groupby(['月','地域','カテゴリ'])['数量'].sum()
data1.plot(kind='line',fontsize=12)
plt.xticks(rotation=-15)

plt.figure(figsize=(20,15))#单位时英寸
plt.subplot(221)
data.groupby(by='月')['数量'].sum().plot()
plt.title('每月的产品购买数量')
plt.subplot(222)
data.groupby(by='月')['売上'].sum().plot()
plt.title('每月的产品销售额')
plt.subplot(223)
data.groupby(by='月')['利益'].sum().plot()
plt.title('每月的消费者购买力')
plt.subplot(224)
data.groupby(by='月')['顧客 ID'].apply(lambda x:len(x.drop_duplicates())).plot()
plt.title('每月的消费人数')

 

 

#每日销量分析
data['オーダー日']=pd.to_datetime(data['オーダー日'],format='%Y%m%d')
data.groupby('オーダー日')['数量'].count().plot(figsize=(12,4))

 

#2014年-2017年销量波动较大
data['月'] = data['オーダー日'].values.astype('datetime64[M]')#保留月份精度的日期
data.groupby('月')['数量'].count().plot(figsize=(12,4))

#用户购买商品数量分析
data.groupby('顧客名')['数量'].count().plot.hist(bins=50)
plt.xlabel('购买数量')
plt.ylabel('人数')
plt.title('用户购买商品数量直方图')
#大多数人都购买个位数产品

#用户购买产品2次及以上情况分析
data_frequency_2 = data.groupby('顧客名').count().reset_index()
#data_frequency_2.head()
data_frequency_2[data_frequency_2['数量'] >=10].groupby('顧客名')['数量'].sum().plot.hist(bins=50)
plt.xlabel('购买数量')
plt.ylabel('人数')
plt.title('用户购买商品10次及以上的用户数量')

#购买数量在3-10个之间的用户占比
data_frequency_gte_1 = data.groupby('顧客名')['数量'].count().reset_index()
data_frequency_gte_1 = data_frequency_gte_1[data_frequency_gte_1['数量']>=3]
values = list(data_frequency_gte_1[data_frequency_gte_1['数量']<=10].groupby('数量')['数量'].count())
values
labels = ['3个','4个','5个','6个','7个','8个','9个','10个']
plt.pie(values,labels=labels,autopct='%1.1f%%')
plt.title('购买数量在3-10个之间的用户占比')
plt.legend()
#消费多数的用户很重要

 

#复购率分析
data.head()
pivot_count = data.pivot_table(index = '顧客名',
                              columns = '月',
                              values = '数量')
pivot_count = pivot_count.applymap(lambda x:1 if x>1 else np.NAN if x==0 else 0)
(pivot_count.sum()/pivot_count.count()).plot()
plt.xlabel('时间(月)')
plt.ylabel('百分比(%)')
plt.title('14-17年每月用户复购率')

 

#回购率
pivot_purchase = data.pivot_table(index = '顧客名',
                 columns = '月',
             values = '数量'
         ).fillna(0)
pivot_purchase.head()
len(pivot_purchase.columns)
                           
def purchase_return(data):
    status = []
    for i in range(47):   
        if data[i]==1:
            if data[i+1]==1:
                status.append(1)
            else:
                status.append(0)
        else:
            status.append(np.NAN)
    status.append(np.NAN)
    return pd.Series(status,pivot_purchase.columns)
pivot_purchase_return=pivot_purchase.apply(purchase_return,axis=1)
(pivot_purchase_return.sum()/pivot_purchase_return.count()).plot()
plt.xlabel('时间(月)')
plt.ylabel('回购率(%)')
plt.title('14-17年每月用户回购率')

def active_status(data):#data 整行数据,共48列
    status = [] #负责存储45个月的状态:unreg|new|acitive|unactive|return
    for i in range(48):
        #本月没有消费
        if data[i] ==0:
            if len(status) ==0: #前面没有任何记录
                status.append('unreg')
            else:#开始判断上一个状态
                if status[i-1]=='unreg':#一直未消费过
                    status.append('unreg')
                else:#new|acitive|unactive|return
                    status.append('unactive')#不管上个月是否消费过,本月都是不活跃用户
            pass
        #本月有消费==1
        else:
            if len(status)==0:#前面没有任何记录
                status.append('new')#第一次消费
            else:
                if status[i-1]=='unactive':
                    status.append('return')
                elif status[i-1]=='unreg':
                    status.append('new')
                else:#new|acitive|return
                    status.append('active')
    return pd.Series(status,pivot_purchase.columns)#值status,列名data_purchase中的列名
pivot_purchase_status = pivot_purchase.apply(active_status,axis=1)#得到用户分层结果
pivot_status_count = pivot_purchase_status.replace('unreg',np.NaN).apply(pd.value_counts)
pivot_status_count.T.plot.area()

 

#每月不同用户的占比
return_rate = pivot_status_count.apply(lambda x:x/x.sum())
return_rate.T.plot()

np.mean(return_rate.T['return'])#回流用户平均值在0.42%左右
#用户的生命周期
time_min = data.groupby('顧客名')['オーダー日'].min()
time_max = data.groupby('顧客名')['オーダー日'].max()
life_time = (time_max-time_min).reset_index()
life_time.describe()

#用户生命周期直方图
life_time['life_time'] = life_time['オーダー日']/np.timedelta64(1,'D')
life_time['life_time'].plot.hist(bins =100,figsize=(12,6))
plt.xlabel('天数')
plt.ylabel('人数')
plt.title('所有用户的生命周期直方图')
print(life_time[life_time['life_time']==0])

#生命周期大于0天的用户,直方图
life_time[life_time['life_time']>0]['life_time'].plot.hist(bins =100,figsize=(12,6))
plt.xlabel('天数')
plt.ylabel('人数')
plt.title('生命周期在0天以上的用户直方图')
#用户生命周期逐渐下降,存在一定用户流失,而忠诚用户越来越少
life_time[life_time['life_time']>0]['life_time'].mean()
#用户平均生命周期在670天
#用户量最大人数是12人

#各时间段的用户留存率
#pd.cut()函数
np.random.seed(666)#保证每次运行程序产生的随机数都是相同的
score_list =np.random.randint(25,100,size=3)
print(score_list)
bins =[0,59,70,80,100]#指定多个区间
score_cut = pd.cut(score_list,bins)
score_cut
[27 70 55]

Out[47]:

[(0, 59], (59, 70], (0, 59]]
Categories (4, interval[int64, right]): [(0, 59] < (59, 70] < (70, 80] < (80, 100]]
user_purchase_retention=pd.merge(left=data,right=time_min.reset_index(),how='inner',on='顧客名',suffixes=('','_min'))
#user_purchase_retention
#计算留存天数
user_purchase_retention['time_diff'] = user_purchase_retention['オーダー日']-user_purchase_retention['オーダー日_min']
#time_diff转成数值
user_purchase_retention['time_diff']=user_purchase_retention['time_diff'].apply(lambda x:x/np.timedelta64(1,'D'))
#生成时间跨度(3个月),判断属于哪个区间
bin = [i*90 for i in range(11)]
user_purchase_retention['time_diff_bin'] = pd.cut(user_purchase_retention['time_diff'],bin)
#统计每个游客,在不同的时间段内消费频率和值(便于稍后判断该用户在某个区间内是不是留存用户)
pivot_retention = user_purchase_retention.groupby(['顧客名','time_diff_bin'])['数量'].sum().unstack()
#判断是否是留存客户(1:留存,0:未留存)
pivot_retention_trans = pivot_retention.fillna(0).applymap(lambda x:1 if x>0 else 0)
#留存率
print(pivot_retention_trans.sum()/pivot_retention_trans.count())
(pivot_retention_trans.sum()/pivot_retention_trans.count()).plot.bar()
plt.xlabel('时间跨度(天)')
plt.ylabel('留存率')
plt.title('各时间段内的用户留存率')
#每个周期是3个月,第一个周期的留存率是12%,前三个月逐渐递减
#留存率最高是15%,最低是9%
#总体来说留存率没有较大变化
time_diff_bin
(0, 90]       0.120448
(90, 180]     0.114846
(180, 270]    0.117647
(270, 360]    0.096639
(360, 450]    0.105042
(450, 540]    0.110644
(540, 630]    0.126050
(630, 720]    0.102241
(720, 810]    0.093838
(810, 900]    0.099440
dtype: float64

Out[56]:

Text(0.5, 1.0, '各时间段内的用户留存率')

 本数据来源于日本某超级市场,通过python进行数据清洗,数据处理,然后运用工具库进行可视化。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值