python实战分析——o2o数据分析


分析目标
1.分析店面客流量是否火爆的影响因素
2.分析顾客的消费情况
3.分析投放优惠劵的使用情况¶

1.导入相关包

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns #绘图模块 基于matplotlib的可视化python包,不能完全替代matplotlib只是一个升级
plt.rcParams['font.sans-serif']=['SimHei'] #显示中文标签
plt.rcParams['axes.unicode_minus']=False   #用来正常显示正负号
%matplotlib inline
#pip install seaborn 

2.加载数据

offline=pd.read_csv('D:\zhangxinfile\python数据实战练习(jupyter lab)\数据分析实战项目资料\O2O\资料\ccf_offline_stage1_train.csv',parse_dates=['Date_received','Date'])
offline.info()#175万的数据,需要转成日期,parse_dates():将指定的列加载成日期的格式,列里面的数据必须为日期类型的

在这里插入图片描述

offline.head(10)#NaT代表时间日期格式的空值

在这里插入图片描述

3.数据的规整

#判断每一列当中有多少个空值
offline.isnull().sum()#相当于对1,0进行计数
#优惠券id以及折扣率,领劵日期,三者可能存在同时等于null的情况

在这里插入图片描述

3.1把Discount_rate中的满减政策转化为折扣率

offline['Discount_rate']=offline['Discount_rate'].fillna('null')
offline.head()

在这里插入图片描述

def discount_rate_opt(s):#s代表每一个元素
    if ':' in s:
        split=s.split(':')
        discount_rate = (int(split[0])-int(split[1]))/int(split[0])
        return round(discount_rate,2)#折扣率保留两位小数
    elif s=='null':
        return np.NaN
    else:
        return float(s)
offline['Discount_rate'] = offline['Discount_rate'].map(discount_rate_opt)
offline.head()

在这里插入图片描述

3.2Coupon_id字段:null代表无优惠券,此时Discount_rate 和Date_received字段无意义

检查coupon——id与Discount_rate和Date_received判断空值和非空值是否为一一对应。

#np.all()#判断一个可迭代的数据中心是否都为true,如果是返回TRUE,否则返回False
np.all([True,True,True])

该函数举例

nan1=offline['Coupon_id'].isnull()  #判断优惠券是否为空
nan2=offline['Date_received'].isnull()#判断领劵日期是否为空
np.all(nan1==nan2)   #如果结果为true 说明之前的猜测:coupon——id和Date_received空值与非空值是一一对应的关系

在这里插入图片描述

nan3=offline['Discount_rate'].isnull()#判断领劵日期是否为空
np.all(nan2==nan3)#如果结果为true 说明之前的猜测:coupon——id和Date_received空值与非空值是一一对应的关系

在这里插入图片描述

3.3 对不同类别的消费进行分析

如果Date=null&coupon_id!=null,有券未消费----(cpon_no_consume)
如果Date=null&coupon_id=null,无券未消费—(no_cpon_no_consume)
如果Date!=null&Coupon_id=null,无券消费(no_cpon_consume)
如果Date!=null&Coupon_id!=null,有券消费(cpon_consume)

cpon_no_consume=offline[(offline['Date'].isnull() & offline['Coupon_id'].notnull())]
no_cpon_no_consume=offline[(offline['Date'].isnull() & offline['Coupon_id'].isnull())]
no_cpon_consume=offline[(offline['Date'].notnull() & offline['Coupon_id'].isnull())]
cpon_consume=offline[(offline['Date'].notnull() & offline['Coupon_id'].notnull())]
print('有券未消费:{}'.format(len(cpon_no_consume)))
print('无券未消费:{}'.format(len(no_cpon_no_consume))) #无意义,不进行后续分析
print('无券消费:{}'.format(len(no_cpon_consume)))
print('有券消费:{}'.format(len(cpon_consume)))
#用券消费的用户7万人相比较其他用户来说,占比较少

在这里插入图片描述

4.数据分析及数据可视化

将原始数据转化为Series中的可识别数据

#绘制饼图占比
consume_status_dict ={'cpon_no_consume':len(cpon_no_consume),'no_cpon_consume':len(no_cpon_consume),'cpon_consume':len(cpon_consume)}
consume_status=pd.Series(consume_status_dict)
consume_status

在这里插入图片描述

#消费方式构成的饼图 (详细解析请参考:https://blog.csdn.net/tefuirnever/article/details/93724227)

#消费方式构成的饼图  (详细解析请参考:https://blog.csdn.net/tefuirnever/article/details/93724227)
fig,ax=plt.subplots(1,1,figsize=(8,10))
consume_status.plot.pie(ax=ax,
                        autopct='%1.1f%%',    #占比情况
                       shadow=True,
                       explode=[0.02,0.05,0.02],
                    textprops={'fontsize':15,'color':'blue'},
                        wedgeprops={'linewidth':1,'edgecolor':'black'},
                        labels=['有券未消费({})'.format(len(cpon_no_consume)),
                        '无券消费({})'.format(len(no_cpon_consume)),
                            '有券消费({})'.format(len(cpon_consume))]
                       )
ax.set_ylabel('')#去除ylabel
ax.set_title('消费占比情况')
plt.legend(labels=['有券未消费','无券消费','有券消费'])
#有券未消费占比55.7%最大,说明大多数人拿完券之后尚未使用
#无券用户占比40%,说明很多人没有使用优惠券,可能优惠前的吸引力必达,客户没在意,可能新用户比较多
#用券消费的用户占比较小:4.3%,说明优惠券使用率不高,可以适当加大优惠券的力度

在这里插入图片描述

另一种更为简单的生成饼图方式(详细过程参考:https://blog.csdn.net/captain811/article/details/79248912?utm_source=app&app_version=5.0.1&code=app_1562916241&uLinkId=usr1mkqgl919blen)

consume_status.plot.pie(
                        autopct='%1.1f%%',    #占比情况
                       shadow=True,
                       explode=[0.02,0.05,0.02],
                    textprops={'fontsize':15,'color':'blue'},
                        wedgeprops={'linewidth':1,'edgecolor':'black'},
                        labels=['有券未消费({})'.format(len(cpon_no_consume)),
                        '无券消费({})'.format(len(no_cpon_consume)),
                            '有券消费({})'.format(len(cpon_consume))]
                       )
plt.title('消费占比情况')
plt.legend(loc=0)

在这里插入图片描述

4.1在有券消费人群中,分析距离和优惠折扣

#各商家对应的顾客到店的平均距离
Merchant_distance=cpon_consume.groupby(by='Merchant_id')['Distance'].mean()
Merchant_distance.sort_values(ascending=False)

在这里插入图片描述

Merchant_distance[Merchant_distance==0]
#有4076个商家有1431个商家的用券消费用户平均范围在500m以内

在这里插入图片描述

#各商家对应的顾客到店消费平均折扣力度
Merchant_discount_rate=cpon_consume.groupby('Merchant_id')['Discount_rate'].mean()  #分组之后取了平均值
Merchant_discount_rate.sort_values(ascending=True)

在这里插入图片描述

Merchant_discount_rate.hist() #y轴的数字代表数量
Merchant_discount_rate.mean()
#由图可知,在哪个折扣的店铺数量最多

4.2持券到店消费人数最多的商家

#对商家进行分组,取出用户id,对用户id进行去重统计数量
popular_merchant=cpon_consume.groupby('Merchant_id')['User_id'].apply(lambda x:len(x.unique())).sort_values(ascending=False)
popular_merchant

在这里插入图片描述

pupular_merchant500=popular_merchant[popular_merchant>500]
pupular_merchant500.name = 'customer_count'  #指定列明为消费者数量(持券消费者)
print(len(pupular_merchant500))
print(pupular_merchant500)
# 共有16家店铺,持券消费人数在500人以上
# 持券消费人数最多商家是5341,持券消费人数为2800(且此为去重后数据,原始数据可能比这个还要多)
# 排名最后的商家,持券消费人数为559人
# 这批商家对优惠券的使用方法得当,消费者喜欢用优惠券进行消费,可以适当借鉴这批商家的推广力度

在这里插入图片描述

4.3持券消费人数在500人以上的商家,连接顾客到店平均距离和平均折扣力度

merchant_pop_dis=pd.merge(left=pupular_merchant500,right=Merchant_distance,on='Merchant_id',how='inner')
merchant_pop_dis.sort_values('Distance',ascending=False)

在这里插入图片描述

merchant_pop_dis_rate=pd.merge(left=merchant_pop_dis,right=Merchant_discount_rate,on='Merchant_id',how='inner')
merchant_pop_dis_rate      

在这里插入图片描述

4.4计算到店消费人数与平均距离和折扣力度的相关系数

#corr(correlation:相关系数),用来计算df数据中列与列的向关性(皮尔逊相关系数)取值为【-1,1】
1代表完全正向关,-1代表完全负相关
正相关,随着变量的增大而增大,反之同理
负相关,随着变量的增大而减小,反之同理
绝对值越大,相关性越大,反之成立

merchant_pop_dis_rate.corr()
#持券消费人数,与距离和折扣率都呈现出负相关,属于生活中的正常现象

在这里插入图片描述

#用热力图展示相关系数
sns.heatmap(data=merchant_pop_dis_rate.corr(),annot=True,cmap='Accent',vmax=1,vmin=-1,linewidths=10)   #可以上网上自行查找
#data是相关系数,,linewidths=10是每个块的间距,annot显示相关系数的值,cmap颜色的范围,vmax去最大值,vmin为最小值

在这里插入图片描述

#由图可知:
1.到店消费人数的多少与顾客到店铺的距离之间呈现负相关, 相关系数为0.31,在0.3-0.5之间为低度相关。
2.到店消费人数的多少与优惠打折力度呈现负相关,相关系数为0.2,在0-0.3之间,相关程度极弱。
综上所述,这些店家之所以火爆,应该是物美价廉导致的,与我们的距离和优惠力度相关性不大

4.5 分析每天当中优惠券的总体发放量与使用量情况

#业务分析:日期(优惠券的发放日期Date_received,使用日期Date)用作图表的x轴
#需要统计每天优惠券发放数量和使用数量

offline['Date'].notnull().sum()     #77.6万的消费记录

在这里插入图片描述

offline['Date_received'].notnull().sum()   #已经发送出105万的优惠券

在这里插入图片描述

#取出存在消费日期的记录,进行升序,在去重
date_sort=offline[offline['Date'].notnull()]['Date'].sort_values().unique()
date_sort[:5]

在这里插入图片描述

#取出存在领券日期的记录,进行升序,在去重
date_receive_sort = offline[offline['Date_received'].notnull()]['Date_received'].sort_values().unique()
date_receive_sort[:5]

在这里插入图片描述

#每天优惠券的使用量(即持券消费人群)
consume_num_everday = cpon_consume[['User_id','Date_received']]
consume_num_everday = consume_num_everday.groupby('Date_received').count()
consume_num_everday = consume_num_everday.rename(columns={'User_id':'count'})
consume_num_everday

在这里插入图片描述

#每天发放的优惠券数量(领券日期!=null的数据,在进行按天分组,计数就可以)
coupon_sendout_everyday = offline[offline['Date_received'].notnull()][['Date_received','User_id']]
coupon_sendout_everyday=coupon_sendout_everyday.groupby('Date_received').count()
coupon_sendout_everyday=coupon_sendout_everyday.rename(columns={'User_id':'count'})
coupon_sendout_everyday

在这里插入图片描述

# 绘制每天发券量和每天用券量
plt.figure(figsize=(18,6))
plt.bar(x=date_receive_sort,height=coupon_sendout_everyday['count'],label='每天发券量')
plt.bar(x=date_receive_sort,height=consume_num_everday['count'],label='每天用券量')
plt.yscale('log')  #对y轴进行对数缩放
plt.legend()
#16年2月为例,用券量级别为1000,发券量在10万左右,两者相差100倍,优惠券使用率还是非常低的

在这里插入图片描述

#绘制每天发券量与用券量比例图
plt.figure(figsize=(18,6))
plt.bar(x=date_receive_sort,height=consume_num_everday['count']/coupon_sendout_everyday['count'],label='百分比')
plt.legend()

在这里插入图片描述

#由图可知,优惠券使用率最高在16年3月底,达到了30%
#使用率最低在16年一月底,最低为3%左右
#总体来看,使用率较低

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值