文章目录
引入包
本项目所用数据为【密码:pfj6】:CDNOW_master.txt
import numpy as np
import pandas as pd
from pandas import DataFrame,Series
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
一、数据预处理
- 本阶段需求
- 读取数据集
df = pd.read_csv('./CDNOW_master.txt')
df.head()
消除列的索引,使用指定索引
df = pd.read_csv('./CDNOW_master.txt',header=None,sep='\s+',names=['user_id','order_dt','order_product','order_amount'])
df.head()
- 查看数据类型
df.info()
- 将order_dt转换成时间序列
df['order_dt'] = pd.to_datetime(df['order_dt'],format='%Y%m%d')
df.info()
- 查看数据的统计描述
df.describe()
- 在源数据中添加一列表示月份:astype(datetime64[‘M’])
df['month'] = df['order_dt'].astype('datetime64[M]')
df.head()
astype的用法:np.astype()
Python中与数据类型相关函数及属性有如下三个: type/dtype/astype
- type() 返回参数的数据类型
- dtype 返回数组中元素的数据类型
- astype() 对数据类型进行 *转换
二、按月对数据分析
- 用户每月花费的总金额
df.groupby(by='month')['order_amount'].sum()
- 绘制曲线图
df.groupby(by='month')['order_amount'].sum().plot()
- 对上图进行细化
plt.figure(figsize=(8,5))
plt.plot(df.groupby(by='month')['order_amount'].sum())
plt.xlabel('order_dt')
plt.ylabel('sum of amount')
plt.title('用户每月花费的总金额')
plt.legend()
- 所有用户每月的产品购买数量
df.groupby(by='month')['order_product'].sum()
df.groupby(by='month')['order_product'].sum().plot()
- 所有用户每月消费的总次数
df.groupby(by='month')['user_id'].count()
- 统计每月消费的人数 【有人会在同一天消费多次】
- unique():去重
- nunique():去重并统计个数
df.groupby(by='month')['user_id'].nunique()
三、用户个体消费数据分析
- 所有用户消费总金额和消费总购买量的统计描述
df['order_product'].sum()
167881
df['order_amount'].sum()
2500315.6300000004
- 各个用户消费金额和香消费产品数量的散点图
user_amount = df.groupby(by='user_id')['order_amount'].sum()
user_product = df.groupby(by='user_id')['order_product'].sum()
plt.figure(figsize=(8,8))
plt.scatter(user_product,user_amount)
plt.xlabel('product')
plt.ylabel('amount')
- 各个用户消费总金额的分布直方图(amount在 1000之内)
df.groupby(by='user_id').sum()
df.groupby(by='user_id').sum().query('order_amount )
query的使用方法
order_amount_1000 = df.groupby(by='user_id').sum().query('order_amount )['order_amount']
order_amount_1000
- 绘出直方图
plt.hist(order_amount_1000,bins=50)
上述结果大部分的消费在(0. , 19.9938)之间,有6.079e+03个人
- 各个用户消费的总数量的分布直方图(消费商品的数量在 100次之内的分布)
user_product_100 = df.groupby(by='user_id').sum().query('order_product )['order_product']
plt.hist(user_product_100,bins=30)
四、用户消费行为分析
- 用户第一次消费的月份分布,和人数统计
如何判定用户第一次消费的月份?
- 用户消费的最小值就是用户首次消费的月份
df.groupby(by='user_id')['month'].min()
人数统计
df.groupby(by='user_id')['month'].min().value_counts()
df.groupby(by='user_id')['month'].min().value_counts().plot()
- 用户最后一次消费的时间分布和认数统计
df.groupby(by='user_id')['month'].max().value_counts()
df.groupby(by='user_id')['month'].max().value_counts().plot()
- 新老客户的占比
- 消费一次为新用户
- 消费多次为老用户
- 判定用户消费的次数(1次还是多次)
* - 求出用户第一次和最后一次消费的时间,若时间相同,则表示用户只消费了一次,否则表示消费多次
first_last_order_dt = df.groupby(by='user_id')['order_dt'].agg(['min','max'])
first_last_order_dt.head()
agg函数的使用:
(first_last_order_dt['min'] == first_last_order_dt['max']).value_counts()
True 12054
False 11516
dtype: int64
- 求出每个用户的总购买量和总消费金额and最后一次消费的时间的表格rfm
rfm = df.groupby(by='user_id').sum()
rfm.head()
user_recently_order_dt = df.groupby(by='user_id')['order_dt'].max()
rfm['R']=user_recently_order_dt
rfm.head()
- R表示客户最近一次交易的时间间隔
* - /np.timedelta64(1,’D’):去除days
- F表示客户购买的商品数量 F越大,表示客户交易越频繁,反之表示客户交易不够活跃
- M表示客户交易的金额 M越大,表示客户价值越高,反之价值越低
- 将R,F, M,作用到rfm中
rfm.columns = ['F','M','R']
rfm
rfm['R'] = df['order_dt'].max() - rfm['R']
rfm
rfm['R'] = rfm['R'] / np.timedelta64(1,'D')
rfm.head()
- 划分客户类型⭐⭐
def rfm_func(x):
level = x.map(lambda x:'1' if x >= 0 else '0')
label = level['R'] + level.F + level.M
d = {
'111':'重要价值客户',
'011':'重要保持客户',
'101':'重要挽留客户',
'001':'重要发展客户',
'110':'一般价值客户',
'010':'一般保持客户',
'100':'一般挽留客户',
'000':'一般发展客户',
}
result = d[label]
return result
rfm['label'] = rfm.apply(lambda x:x-x.mean(),axis=0).apply(rfm_func,axis=1)
rfm.head()
五、用户的生命周期
- 统计每个用户每个月的消费次数
df.pivot_table(index='user_id',values='order_dt',aggfunc='count').head()
df.pivot_table(index='user_id',values='order_dt',aggfunc='count',columns='month')
user_month_order_count = df.pivot_table(index='user_id',values='order_dt',aggfunc='count',columns='month',fill_value=0)
user_month_order_count.head()
- 统计出每个用户每个月是否消费,消费记录为1 否则为0
- applymap()函数用于对DataFrame中的每一个元素执行相同的函数操作
- apply()函数主要用于对DataFrame中的某一column或row中的元素执行相同的函数操作。
df_purchase = user_month_order_count.applymap(lambda x:1 if x>=1 else 0)
df_purchase.head()
- 对每月得用户活跃成分进行用户划分⭐⭐⭐
def active_status(data):
status = []
for i in range(18):
if data[i] == 0:
if len(status) > 0:
if status[i-1] == 'unreg':
status.append('unreg')
else:
status.append('unactive')
else:
status.append('unreg')
else:
if len(status) == 0:
status.append('new')
else:
if status[i-1] == 'active':
status.append('return')
elif status[i-1] == 'unreg':
status.append('new')
else:
status.append('active')
return status
pivoted_status = df_purchase.apply(active_status,axis=1)
pivoted_status.head()
- 需要将上述返回的Series封装到DataFrame中⭐⭐
pivoted_status.values
pivoted_status.values.tolist()
df_purchase_new = DataFrame(data=pivoted_status.values.tolist(),index=df_purchase.index,columns=df_purchase.columns)
df_purchase_new.head()
- 每月【不同活跃】用户的计数⭐
purchase_status_ct = df_purchase_new_apply(lambda:pd.value_counts(x)).fillna(0)
转置进行最终结果的查看
df_purchase_new.apply(lambda x:pd.value_counts(x))
- 将NaN用0填充
df_purchase_new.apply(lambda x:pd.value_counts(x)).fillna(0)
- 翻转
df_purchase_new.apply(lambda x:pd.value_counts(x)).fillna(0).T
Original: https://blog.csdn.net/HG0724/article/details/121070931
Author: 胜天半月子
Title: 项目实战–用户消费数据分析
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/600297/
转载文章受原作者版权保护。转载请注明原作者出处!