赞
踩
首先,加载用户的消费数据。
columns=["user_id","order_dt","order_product","order_amount"]
df = pd.read_csv('data.txt', sep='\s+', names=columns)
user_id:客户ID
order_dt:订单日期
order_product:订单产品
order_amount:订单金额
使用groupby+agg
聚合的方法得到统计结果,并按order_product降序排序。
(
df.groupby("user_id",as_index=False)
.agg({"order_product":np.sum,"order_amount":np.mean})
.sort_values(['order_product'],ascending=False)
)
(
df.groupby("order_month")['order_amount'].sum()
.plot(figsize=(10,6),marker='o')
)
一笔订单对应的总金额分布
df.plot.scatter(x="order_product",y="order_amount")
每个用户每笔订单对应的总金额分布
(
df.groupby("user_id")[['order_product','order_amount']].sum()
.plot.scatter(x="order_product",y="order_amount")
)
plt.figure(figsize=(12,4))
plt.subplot(121)
df.order_amount.hist(bins=30) #订单金额直方图分布
plt.subplot(122)
df.groupby("user_id").order_product.sum().hist(bins=30) #每个用户购买总量的直方图
plt.tight_layout()
反映出大部分人的消费额和购买数量都是较低,符合一般消费规律。
复购率定义:在一个月内消费次数2次及以上的用户所占的比例。
首先通过透视表pivot_table
统计每个用户各月的消费次数,然后加工出复购的标识,将每月消费次数2次以上的记为1,一次的记为0,没有消费的记为NaN。
pc = df.pivot_table(index="user_id",
columns="order_month",
values="order_date",
aggfunc="count").fillna(0)
pct = pc.applymap(lambda x:1 if x>=2 else np.NAN if x==0 else 0)
# 按月统计复购率
pct.mean().plot(figsize=(10,6),marker='o')
回购率:本月消费并在下月继续消费的客户占比
这里的定义是在一个月之内只要消费次数大于1即可认为是消费。
步骤:
首先,加工出本月有过消费的标识字段,通过轴旋转变为宽表形式。
对if_has_order是否消费变量向上偏移一个单位
计算加工出是否回购变量if_reorder
可视化
pp = ( pc.applymap(lambda x:1 if x > 1 else 0) .stack() .to_frame(name='if_has_order') .reset_index() ) # 回购计算逻辑 pp['if_has_order_next_month'] = pp['if_has_order'].shift(-1) pp['if_reorder'] = 0 pp.loc[(pp1['if_has_order'] == 1)&(pp['if_has_order_next_month']==1),'if_reorder'] = 1 pp.loc[(pp1['if_has_order'] == 1)&(pp['if_has_order_next_month']==0),'if_reorder'] = 0 pp.loc[(pp1['if_has_order'] == 0),'if_reorder'] = np.nan ( pp.pivot_table(index='order_month',values='if_reorder',aggfunc='mean') .plot(figsize=(10,6),marker='o') )
整体回购率约为25%,其中新客户质量低于老客户,老客户的忠诚度较高。最后一期降为0是由于没有下一期数据,可以视为异常忽略。
根据客户的活跃程度可将客户分为沉默户、新户、活跃户、不活跃户、回流用户,具体定义如下:
沉默户:从未发生过消费的客户
新户:第一次消费的客户
活跃户:老客户,在时间窗口内发生过消费的客户
不活跃户:老客户,在时间窗口内未发生过消费的客户
回流:上个月未消费但本月消费过的客户
为了给每个客户在各观察月打上客户分层标签,需要借助一些辅助列。通过分组内偏移、排序、累计求和等方法实现。分组内的各种骚操作可以了解东哥的pandas进阶宝典。
pp['order_month'] = pd.to_datetime(pp['order_month'])
pp = pp.sort_values(['user_id','order_month'],ascending=[True,True])
# 加工辅助列
pp['if_has_order_last_month'] = pp.groupby(['user_id'])['if_has_order'].transform(lambda x:x.shift(1))
pp['if_has_order_next_month'] = pp.groupby(['user_id'])['if_has_order'].transform(lambda x:x.shift(-1))
pp['order_rank'] = pp.groupby(['user_id'])['order_month'].transform(lambda x: x.rank(method='first'))
pp['order_cumsum'] = pp.groupby(['user_id'])['if_has_order'].transform('cumsum')
然后,生成客户分层的变量user_status,按照不同的条件进行赋值。
pp['user_status'] = '' # silent pp.loc[(pp['order_cumsum']==0),'user_status'] = 'silent' # new pp.loc[(pp['order_rank']==1)&(pp['if_has_order']==1),'user_status'] = 'new' pp.loc[(~(pp['order_rank']==1))&(pp['if_has_order']==1)&(pp['order_cumsum']==1),'user_status'] = 'new' # unactive pp.loc[(pp['order_cumsum']>0)&(pp['if_has_order']==0),'user_status'] = 'unactive' # active pp.loc[(pp['order_cumsum']>1)&(pp['if_has_order']==1)&(pp['if_has_order_last_month']==1),'user_status'] = 'active' # return pp.loc[(pp['order_cumsum']>1)&(pp['if_has_order']==1)&(pp['if_has_order_last_month']==0),'user_status'] = 'return'
最后用面积图进行分层客户的可视化。蓝色的面积表示活跃客户,绿色表示回流客户,4个月后基本稳定,说明没有新客。
pp1 = pp.replace("silent",np.NaN)
pp2 = pp1.pivot_table(index='order_month',columns='user_status',values='user_id',aggfunc='count',fill_value=0)
pp2.plot.area(figsize=(12,6))
按客户ID分组对订单金额求和,然后计算每个客户的订单总和占累计求和的比例。
ua = df.groupby("user_id").order_amount.sum().sort_values().reset_index()
ua["amount_cumsum"] = ua.order_amount.cumsum()
ua["amount_sum"] = ua.order_amount.sum()
ua["prop"] = ua.apply(lambda x:x.amount_cumsum/x.amount_sum,axis=1 )
ua.prop.plot(figsize=(12,6))
可以看到,前20000的客户贡献了40%的消费,后面4000的客户贡献了60%的金额,呈现二八倾向。
求出每个客户的最早和最晚的消费日期作差得到最早和最晚的时间间隔时长,即为客户的生命周期。
user_purchase = df[["user_id","order_product","order_amount","order_date"]]
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).dt.days.hist(bins=40,figsize=(10,6))
大部分客户只消费了一次,开始时间和结束时间都是一样的所以相减为0,因此大部分客户集中在0。
剔除只消费1次的,对消费2次及以上的客户进行分析。
lft = (order_date_max-order_date_min).dt.days
lft[lft>0].hist(bins=100,figsize=(10,6))
消费2次及以上的客户生命周期呈现双峰趋势,处于左峰部分的客户生命周期在0至100天内,虽然消费了2次但没有能持性,因此在该部分客户首次消费30天后应该进行主动营销引导后续消费;处于右侧峰部分的客户生命周期集中在400天以后,属于忠诚用户;而集中在50-300天的属于普通型的生命周期。
以上就是“pandas实战:用户消费行为画像”的全部内容,希望对你有所帮助。
关于Python技术储备
学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!
一、Python所有方向的学习路线
Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
二、Python必备开发工具
三、Python视频合集
观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
四、实战案例
光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
五、Python练习题
检查学习结果。
六、面试资料
我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
最后祝大家天天进步!!
上面这份完整版的Python全套学习资料已经上传至CSDN官方,朋友如果需要可以直接微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。