• 【数据分析案例】用户消费行为


    """
    user_ud 用户ID
    order_dt: 购买日期
    order_products: 购买产品数
    order_amount: 购买金额
    """
    
    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    
    
    pd.set_option('display.max_columns', None)   #显示完整的列
    pd.set_option('display.max_rows', None)  #显示完整的行
    
    
    plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
    
    
    columns = ['用户ID','购买日期','购买产品数','购买金额']
    
    
    data = pd.read_table('CDNOW_master.txt',names=columns,sep='s+')  # names设置表头   s+任意的空字符串
    
    
    
    
    # 查看是否存在缺失值
    # print(data.info())
    
    # order_dt: 购买日期 转换成日期类型
    
    # def time_style(x):
    #    time = str(x)[0:4] + "-" +  str(x)[4:6]  + "-" + str(x)[6:8]
    #    return time
    # data['购买日期'] = data['购买日期'].apply(time_style)
    
    data['购买日期'] = pd.to_datetime(data['购买日期'],format="%Y%m%d")
    # print(data.head(3).dtypes)
    
    # 计算每个用户购买商品的平均数量
    # print(data.groupby('用户ID')['购买产品数'].mean())
    
    # 计算所每个用户购买商品的平均花费
    # print(data.groupby('用户ID')['购买金额'].mean())
    
    # describe是描述统计 # 计算所有用户购买商品的平均数量
    # print(data.describe())
    
    #    M 对月进行统计
    data['month'] = data['购买日期'].values.astype('datetime64[M]')
    
    
    print(data.head())
    
    
    
    
    
    # 用户每月花费的总金额
    use_months_by = data.groupby('month')['购买金额'].sum()
    # print(use_months_by)
    #
    # plt.figure(figsize=(5,4))
    # plt.plot(use_months_by.index,use_months_by.values,label="用户每月花费的总金额")
    # plt.legend(loc=0)
    # plt.savefig("用户每月花费的总金额.jpg")
    # plt.show()
    
    
    # 所有用户每月的产品购买量
    # print(data.groupby('month')['购买产品数'].sum())
    
    
    # 所有用户每月的消费总次数
    # print(data.groupby('month')['用户ID'].count())
    
    # 统计每月的消费人数    # 同一個人可能消費多次,所以 消费人数 只能是唯一的 .nunique() 去重后余下的
    # print(data.groupby('month')['用户ID'].nunique())
    
    
    
    
    
    # 各个用户消费总金额和消费总次数的统计描述
    # print("各个用户消费总金额",data.groupby('用户ID')['购买金额'].sum())
    # print("各个用户消费总次数",data.groupby('用户ID')['购买产品数'].nunique())
    
    
    
    # print(data.groupby('用户ID').sum().describe())
    
    # 各个用户消费总金额和消费总次数的散点图
    # plt.scatter(data.groupby('用户ID').sum()['购买产品数'],
    #             data.groupby('用户ID').sum()['购买金额'])
    # plt.xlabel("购买产品数")
    # plt.ylabel("购买金额")
    # plt.show()
    
    
    
    
    # 各个用户消费总金额的直方分布图(消费金额在1000之内的分布)
    # 總結:在groupby条件后直接限制条件, 限制条件后的结果取值 作图
    # data_f = data.groupby('用户ID').sum().query(" 购买金额 < 1000 " )['购买金额']
    # print(data_f)
    # plt.hist(data_f,bins=10) # bins柱子的个数
    # plt.show()
    
    
    
    # 各个用户消费总次数的直方分布图(消费次数在于100内)
    # by_number = data.groupby('用户ID').sum().query('购买产品数 < 100')['购买产品数']
    # print(by_number)
    # plt.hist(by_number,bins=30)
    # plt.show()
    
    
    # 消费次数在100以内的  只有8个人消费次数超过100
    # print((data['用户ID'].value_counts() < 100).value_counts() )       # 每个data['用户ID']出现的次数(出现次数 == 消费的次数)
    # True     23562
    # False        8
    
    
    # 用户第一次消费的月的分布,和人数统计   month已经转成时间数据类型
    # print(data.groupby('用户ID')['month'].min())  # 分组出用户ID,然后选出分组后每个用户ID最小的那个
    # print(data.groupby('用户ID')['month'].min().value_counts()) # 每个月份的人数统计
    # data.groupby('用户ID')['month'].min().value_counts().plot()  # 首购分布图
    # plt.show()
    
    
    
    
    # 用户最后一次消费的时间分布,人数统计
    # print(data.groupby('用户ID')['month'].max())
    # print(data.groupby('用户ID')['month'].max().value_counts())
    # data.groupby('用户ID')['month'].max().value_counts().plot() # 最后一次购买的时间分布图
    # plt.show()
    
    
    # 新用户 (只购买一次)
    
    # 获取每个用户的首购 跟尾够
    # 第一种方式(结果是错误的)因为是一次消费的用户,所有只要挑出购买产品数为1的 )  学到的知识是 判断两数组对比方式
    # data_left = data.groupby("用户ID")['month'].agg(['min','max']) # 得到min max日期
    # print((data_left['min'] == data_left['max']).value_counts())
    
    # print( (data.groupby("用户ID")['购买产品数'].sum() == 1).value_counts().values) # 第二种方式[X,X1]
    
    
    
    
    # 每个用户的总购买量 总消费金额  and 最近一次消费的表格rfm    (每个用户在最近的一次消费)
    rfm = data.pivot_table(index='用户ID',aggfunc={'购买产品数':'sum','购买金额':'sum','购买日期':'max',})
    
    # 每个用户最近一次交易的时间间隔  (购买日期 - 购买日期的最大值) || 去掉days:  / np.timedelta64(1,'D')
    rfm['R'] = -(rfm['购买日期'] - rfm['购买日期'].max()) / np.timedelta64(1,'D')
    # 修改名字
    rfm.rename(columns={'购买金额':'M',"购买产品数":"F"},inplace=True)
    # print(rfm.head())
    
    
    
    # # 分层次
    def rfm_func(x):
        level = x.map(lambda x:'1' if x >= 0 else '0') # 如果是负数的就是0,不是就是1
        laber = level.R + level.F + level.M  # 拼接成 d 对应的数值  进行区分客户等级
        d = {
            '111':'重要价值客户',
            '011':'重要保持客户',
            '101':'重要挽留客户',
            '001':'重要发展客户',
            '110':'一般价值客户',
            '010':'一般保持客户',
            '100':'一般挽留客户',
            '000':'一般发展客户',
        }
        result = d[laber]
        return result
    
    
    rfm['laber'] =rfm[['R','F','M']].apply(lambda x: x - x.mean()).apply(rfm_func,axis=1)
    # print(rfm)
    
    # print(rfm.groupby('laber').count())
    
    #
    # rfm.loc[rfm.laber == '重要价值客户','color'] = 'g'
    # rfm.loc[~(rfm.laber == '重要价值客户'),'color'] = 'r'
    # rfm.plot.scatter("F",'R',c = rfm.color)
    # plt.show()
    
    
    
    
    
    # 统计每个用户每个月的消费次数
    user_order_count_data = data.pivot_table(index='用户ID',values='购买日期',aggfunc='count',columns='month').fillna(0).head()
    # 1               0           0           0           0           0           0
    # 2               0           0           0           0           0           0
    
    
    
    # 统计每个用户每个月是否消费 消费记录为1 否者记录消费为0
    # apply 每一行的数据
    # applymap() 每一个数据都执行一遍
    data_purchase = user_order_count_data.applymap(lambda x:1 if x >= 1 else 0)
    # print(data_purchase)
    
    
    
    
    # 活跃用户判断
    
    col = ['1997-01-01', '1997-02-01', '1997-03-01', '1997-04-01',
           '1997-05-01', '1997-06-01', '1997-07-01', '1997-08-01',
           '1997-09-01', '1997-10-01', '1997-11-01', '1997-12-01',
           '1998-01-01', '1998-02-01', '1998-03-01', '1998-04-01',
           '1998-05-01', '1998-06-01']
    
    
    def active_status(data):
        status = []
        for i in range(18):
    
            # 若本月没有消费
            if data[i] == 0:
                if len(status) > 0:
                    if status[i - 1] == 'unreg':  # 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] == 'unactive':
                        status.append('return')  # 回流用户
                    elif status[i - 1] == 'unreg':
                        status.append('new')  # 新用户
                    else:
                        status.append('active')  # 活跃用户
        return pd.Series(status, index=col)
    
    p_status = data_purchase.apply(active_status,axis=1)  # 将每一行数据执行函数一次
    # print(p_status)
    
    
    print(p_status.replace('unreg',np.NAN).apply(lambda x:pd.value_counts(x)).T)
  • 相关阅读:
    近期学习情况
    java连接数据库的两种方法总结
    近两个星期学习成果
    云笔记第一阶段总结
    圆面积
    C++计算器项目的初始部分
    C++视频课程
    A+B Format
    大一下学期的自我目标
    Kohana的请求流
  • 原文地址:https://www.cnblogs.com/wanghong1994/p/12950605.html
Copyright © 2020-2023  润新知