python电商用户消费数据分析实战(一)_第1页
python电商用户消费数据分析实战(一)_第2页
python电商用户消费数据分析实战(一)_第3页
python电商用户消费数据分析实战(一)_第4页
python电商用户消费数据分析实战(一)_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

python电商⽤户消费数据分析实战(⼀)数据导⼊:importpandasaspdimportnumpyasnpimportmatplotlib.pyplotaspltfromdatetimeimportdatetime%matplotlibinline%matplotlibinline是个魔法函数:可以在Ipython编译器⾥直接使⽤,功能是可以内嵌绘图,并且可以省略掉plt.show()这⼀步columns=['user_id','order_dt','order_products','order_amount']df=pd.read_csv(r'D:/CDNOW_master.txt',names=columns,sep='\s+')由于原数据没有表头,⼿动输⼊,并以任意空格|s+为分隔符号这⾥最好不要⽤pd.read_table,会弹警告D:\pyyyth\lib\site-packages\ipykernel_launcher.py:2:FutureWarning:read_tableisdeprecated,useread_csvinstead.显⽰未来可能出问题,所以换成pd.read_csv基本数据()查看下读取后的数据集概况这个数据集是被预处理过的,所以没有空值df.describe()这是个统计函数,可以获得平均值、最⼤值、最⼩值、标准差等很多信息平均每笔订单购买2.4个商品,⽽标准差在2.3,波动不算⼤。中位数在2个商品,⽽75分位在3个商品,可以看出⼤部分订单购买的商品都不算多,最⼤值在99个,所以⼤部分订单都集中在⼩额,此数据符合⼆⼋模型,也就是说80%左右的⽤户贡献⼩额消费,20%左右的⽽⽤户贡献⼤额消费。df.head()这个函数读取前5⾏基于⽤户分析user_grouped=df.groupby('user_id').sum()user_grouped.head()利⽤groupby创建⼀个新对象user_grouped可以直观的看出⽤户的消费量user_grouped.describe()从⽤户⾓度每个⽤户平均购买7个产品,最多的购买了1033个产品,⽤户的平均消费额在106元,⽽标准差在240,波动较⼤;且在50%分位的消费只才3个和43元,⽽到75%分为的消费值才和平均值接近,所以存在⼩部分的⼤额消费⽤户聚集在75%分为以上,即为存在⼩部分⼤额消费⽤户。基于时间df.groupby('month').order_amount.sum().plot()可以看出第⼀个季度的销量⾮常⾼,⽽后⾯的销量都很平稳,这种趋势是异常的,可能的原因猜测是应为促销或者统计的早期⽤户出了问题,有异常值。⽤户质量分析复购率分析pivoted_counts=df.pivot_table(index='user_id',columns='month',values='order_dt',aggfunc='count').fillna(0)#对消费次数进⾏数据透视,利⽤userid做索引,month做列,⽤count⽅法计算order_dt出现次数(统计有多少必订单)#有空值(NaN)⽤0进⾏填充cloumns_month=df.month.sort_values().astype('str').unique()pivoted_counts.columns=columns_monthpivoted_counts.head()这⾥统计了具体次数,观察发现只有0-2次三种情况,所以进⼀步规范可以得出更直观的数据。pivoted_counts_transf=pivoted_counts.applymap(lambdax:1ifx>1elsenp.NaNifx==0else0)#applymap()将⾃定义的匿名函数lambda作⽤于df的所有元素,两次返回1,⼀次NaN,零次返回0pivoted_counts_transf.head()利⽤applymap对每个元素进⾏转换后可以直观看出复购情况,为了直观观察复购率,所以转换成折现图观察(pivoted_counts_transf.sum()/pivoted_counts_transf.count()).plot(figsize=(10,4))#复购次数样/本数量=复购率替代法计算复购率:sum()和count()都会忽略NaN,所以复购率统计了消费两次以上的⽤户数量占全部⽤户数量的百分⽐可以看出回购率在早期因为⼤量新客户加⼊所以不⾼,1997-01就只有6%,⽽后因为稳定的客源,⽼客户的回购率上升后就稳定在20%左右,新客和⽼客的回购率差距在三倍左右。回购率分析#对消费⾦额进⾏透视,⽤平均值统计pivoted_amount=df.pivot_table(index='user_id',columns='month',values='order_amount',aggfunc='mean').fillna(0)columns_month=df.month.sort_values().astype('str').unique()pivoted_amount.columns=columns_monthpivoted_purchase=pivoted_amount.applymap(lambdax:1ifx>0else0)pivoted_purchase.head()pivoted_amount=df.pivot_table(values='order_dt',index='user_id',columns='month',aggfunc='count').fillna(0)#转化数据,有过购买的为,没有购买的为10pivoted_purchase=pivoted_amount.applymap(lambdax:1ifx>0else0)pivoted_purchase.head()#定义函数,每个⽉都要跟后⾯⼀个⽉对⽐下,本⽉有消费且下⽉也有消费,则本⽉记1,为下⽉没有消费则为0,本⽉没有消费则为NaN,由于最后个⽉没有下⽉数据,规定全为NaNdefpurchase_return(data):status=[]foriinrange(17):ifdata[i]==1:ifdata[i+1]==1:status.append(1)ifdata[i+1]==0:status.append(0)else:status.append(np.NaN)status.append(np.NaN)returnpd.Series(status)#应⽤并且绘图pivoted_purchase_return=pivoted_purchase.apply(purchase_return,axis=1)pivoted_purchase_return.head()因为回购率是指连续购买的概率,所以要写⼀个函数purchase_return来统计连续购买的概率并化成表(pivoted_purchase_return.sum()/pivoted_purchase_return.count()).plot(figsize=(10,4))回购率=回购⼈数/总⼈数由图可以看出⽤户的回购率⾼于复购率,波动性较强,新⽤户回购率在15%左右,⽼客的差距不⼤。由回购率和复购率可知,新客质量⾼于⽼客,⽽⽼客的忠诚度(回购率)较好,消费频次稍次;所以应该努⼒留住新客,多发放优惠等给新客,⽽⽼客也应该有所挽留避免流失。销售额分布user_amount=df.groupby('user_id').order_amount.sum().sort_values().reset_index()#建⽴⼀个新对象对订单数求和并从⼩到⼤排序user_amount['amount_cumsum']=user_amount.order_amount.cumsum()#cunsun是累加函数,累加计算⾦额user_amount.tail()按照⽤户id计算订单数并求和,然后⽤cumsum()对每个⽤户的所有订单⾦额求和amount_total=user_amount.amount_cumsum.max()#计算⾦额总和user_amount['prop']=user_amount.apply(lambdax:x.amount_cumsum/amount_total,axis=1)#转换成百分⽐user_amount.tail()转换成百分⽐user_p.plot()横坐标是⽤户排序,纵坐标是贡献所占百分⽐,可以看出前20000个⽤户贡献了40%的销售额,之后的4000⼈⽤户贡献了60%的销售额,符合⼆⼋分布;同时也体现了此数据的长尾效应,应该对⼩额消费进⾏刺激,从⽽达成⼩额消费者像⼤额消费者转化。销售量分布user_counts=df.groupby('user_id').order_dt.count().sort_values().reset_index()user_counts['counts_cumsum']=user_counts.order_dt.cumsum()counts_total=user_counts.counts_cumsum.max()user_counts['prop']=user_counts.apply(lambdax:x.counts_cumsum/counts_total,axis=1)user_p.plot()也符合⼆⼋分布⽤户⽣命周期user_purchase=df[['user_id','order_products','order_amount','order_date']]#按⽤户id分组后按消费的最后⼀天和最早⼀天排序order_date_min=user_purchase.groupby('user_id').order_date.min()order_date_max=user_purchase.groupby('user_id').order_date.max()(order_date_max-order_date_min).head(10)因为上⾯统计得出⽤户多数1-3⽉注册,所以得出的是⽤户1-3⽉注册到最后⼀次消费的⽣命周期。life_time['life_time']=life_time.order_date/np.timedelta64(1,'D')#转换单位life_time[life_time.life_time>0].life_time.hist(bins=100,figsize=(12,6))#将⽣存周期不到⼀天的排除后做直⽅图可以看出⽣命周期在1天的⽤户虽然也多,但是在20天左右顾客开始迅速下降,⽽到了120天左右⽤户已经降到最低点,所以应该在20天和120天给⽤户选择性的递送优惠券等尽量留住顾客。life_time[life_time.life_time>0].life_time.mean()可以得出⽤户的平均⽣命周期是276天左右,所以也应该在此时间点进⾏⼀定的优惠活动留存顾客。⽤户留存率user_purchase_retention=pd.merge(left=user_purchase,right=order_date_min.reset_index(),how='inner',on='user_id',suffixes=('','_min'))#merge类似于sql的join,将⽤户消费表和⽤户最早开始消费的时间内联在⼀个表⾥user_purchase_retention['order_date_diff']=user_purchase_retention.order_date-user_purchase_retention.order_date_min#得出⽤户留存时间order_date_diffuser_purchase_retention['date_diff']=user_purchase_retention.order_date_diff.apply(lambdax:x/np.timedelta64(1,'D'))#转换成标准形式user_purchase_retention.head(10)利⽤merge函数得出⽤户⾄今留存时间bin=[0,30,60,90,120,150,180]#给出0-30天,30-60天的距离分组user_purchase_retention['date_diff_bin']=pd.cut(user_purchase_retention.date_diff,bins=bin)#pd.cut⽤给出的bin的距离给数据分组计算购买总额pivoted_retention=user_purchase_retention.groupby(['user_id','date_diff_bin']).order_amount.sum().unstack()#按照⽤户id和区间排序,unstack()规定不能折叠pivoted_retention.head()⽤透视得出⽤户在第⼀次消费后的在后续各个时间段的消费总额pivoted_retention_trans=pivoted_retention.fillna(0).applymap(lambdax:1ifx>0else0)#NaN0⽤填充,并将回购次数⼤于的转化为1,其余为00(pivoted_retention_trans.sum()/pivoted_retention_trans.count()).plot.bar()同样⽤之前的⽅法将所赐消费的转为1其他转为0从⽽得到⽤户留存率,可以发现第⼀个⽉的留存路在45%左右,⽽第⼆个⽉就将到35%,后⾯就稳定在25%左右,说明在前三个⽉留住顾客⼗分重要,如何在前三个⽉进⾏积极的营销也是需要注意的重点。问题总结1)导⼊数据后时间显⽰问题order_dt(购买⽇期)现在是⼀串数字没有太多意义解决:对order_dt进⾏转换df['order_date']=pd.to_datetime(df.order_dt,format="%Y%m%d")df['month']=df.order_date.values.astype('datetime64[M]')df.head()法⼀:导⼊的datetime库可以调⽤to_datetime()对特定字符串或者数字转换成时间格式,format⽤于参数匹配。%Y——4位年份(这⾥的1997等)%m——2位⽉份(这⾥的01)%d——2位⽇期(这⾥的01)%h——⼩时%M——分钟,和⽉份⼤⼩写区分%s——秒法⼆:利⽤pandas⾃带astype转换,[M]转换成⽉份,所以转换后具体哪⼀天会被模糊成01,也就是只计⼊每⽉1⽇。选择⽉份做主要事件窗⼝因为对于⼩额消费来说按具体天数计算太琐碎,按照年份过于模糊。2)基于⽉份分析时销售集中在前三个⽉,后⾯销售额断崖式下降,这种数据是异常的。解决:根据⽇常经验可以假设是⽤户的原因(⽤户注册时间等)、统计误差原因、销售⽹站的原因(促销活动等),每⼀个我们进⾏⼀定的分析来排除。假设①:⽹站促销df.plot.scatter(x='order_products',y='order_amount')绘制每笔订单的散点图,可以看出有消费⾦额和商品量有⼀定的规律,在消费⾦额在0-20的时候消费量没有在1000以上的,⽽价格在30-100等⾼价的时候就包括了⼤部分1000件以上的订单,可以看出不是促的原因,数据也符合其低额销量少,⾼额销量多的特点。假设②:统计误差df.groupby('user_id').sum().plot.scatter(x='order_amount',y='order_products')绘制⽤户散点图,可以看出⽤户消费⾦额和商品量成正⽐,离群点极少,所以⽤户的消费规律性也很强,⽐较健康。假设③:⽤户原因消费量统计plt.figure(figsize=(12,4))#指定宽和⾼plt.subplot(121)#换分为1⾏2列组成的区块,并获取到第⼀块区域df.order_amount.hist(bins=30)#hist绘制直⽅图,指定20竖条plt.subplot(122)df.groupby('user_id').order_products.sum().hist(bins=30)⽤plt.subplot绘制两个⼦图,分别是1⾏2列的两个区块,可以看出⼤部分消费者消费能⼒不⾼,都集中在0-200元区间,⾼消费的⽤户⼏乎看不到。第⼀次消费时间统计df.groupby('user_id').month.min().value_counts()groupby之后求⽉份的最⼩值并计数,也就是求出每个⽤户第⼀次消费的⽉份,并统计每个⽉份第⼀次消费的⽤户数,可以清晰的看出所有⽤户都是在1-3⽉进⾏第⼀次消费,所以可以得出数据可能是统计了某个时段内注册开始消费的⽤户在之后18个⽉的消费⾏为。这也可以解释为什么⼤部分消费都在1-3⽉,因为⼤部分⽤户都在这⼏个⽉份注册并进⾏第⼀次消费。最后⼀次消费时间统计df.groupby('user_id').month.max().value_counts()同样可以看出⼤部分⽤于在1997的1-3⽉进⾏消费后⾯逐渐减少,1998的5-6⽉的消费也偏多,可以看出⼤部分⽤户在第⼀次消费之后就不再消费,消费量也逐⽉减少。综上所述,⽤户消费集中在1-3⽉是因为此数据集给出的是1-3⽉注册购买的⽤户的数据,所以1-3⽉的购买量极⾼。3)统计时间(年⽉⽇)出现具体时间点的问题统计完之后本来希望的列名称只是具体⽉份,但是因为利⽤pandas⾃带astype转换,[M]转换成⽉份,时间也模糊成了(00:00:00),这些时间点是没有意义的。解决:cloumns_month=df.month.sort_values().astype('str').unique()pivoted_counts.columns=columns_month转换成str型截掉时间(时分秒)就可以去掉4)数据类型不允许⽤于绘图得到的⽣命周期类型是timedelta6

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论