搭建宽表作用,就是为了让业务部门的数据分析人员,在日常工作可以直接提取所需指标,快速做出对应专题的数据分析。在实际工作中,数据量及数据源繁多,如果每个数据分析人员都从计算加工到出报告,除了工作效率巨慢也会导致服务器资源紧张。因此建设数据集市层,包含了该宽表层并在非工作时间做自动生成。

本文引用CDNow网站的一份用户购买CD明细数据,梳理业务需求,搭建一套数据宽表。

该CD数据包括用户ID,购买日期,购买数量,购买金额四个字段(此项目中用userid,datatime,products,amounts字段来表示)

业务逻辑参考文章:zhuanlan.zhihu.com/p/109767465

指标维度整理如下:

(实际业务场景中,由于获取的数据维度非常多,基础指标及衍生指标的加工最后有几千个指标都很正常,本次该数据集主要用于提出思路。另外,基于机器学习算法自动生成的衍生指标不在本次文章讨论范围,本次宽表指标主要是从业务角度出发,开发具备可解释性指标)



ps:指标名、统计口径、数据类型、小数位的统一非常重要

数据加载

  1. import pandas as pd
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. from datetime import datetime
  5. %matplotlib inline
  6. df = pd.read_table('CDNOW_master.txt',delim_whitespace=True,header=None,names=['userid','datetime','products','amounts'])
  7. df['datetime'] = pd.to_datetime(df['datetime'],format='%Y%m%d')
  8. #加入月维度
  9. df['month'] = df['datetime'].values.astype('datetime64[M]')
  10. df.head()

一、时间维度

①基础指标:销售额/销量/消费次数/消费人数,可用以支撑RMF模型

  1. #每月的总销售额/销量/消费次数
  2. df_m_total_1 = df.pivot_table(index='month',values=['amounts','userid','products',]
  3. ,aggfunc={'amounts':'sum','userid':'count','products':'sum'})
  4. #每月的消费人数
  5. df_m_total_consume = pd.DataFrame(df.groupby('month')['userid'].nunique())
  6. #合并
  7. df_m_total = pd.merge(df_m_total_1, df_m_total_consume, on=['month'])
  8. #修改列名
  9. df_m_total.columns = ['m_total_amount','m_total_count','m_total_volumn','m_total_consume']

②活跃度指标:新用户/活跃用户/不活跃用户/回流用户

  1. #每个用户每月的消费次数
  2. pivoted_counts = df.pivot_table(index='userid',columns='month',values='datetime',aggfunc='count').fillna(0)
  3. #1代表本月消费,0代表未消费
  4. df_purchase = pivoted_counts.applymap(lambda x:1 if x>0 else 0)
  5. col = ['1997-01-01', '1997-02-01', '1997-03-01', '1997-04-01',
  6. '1997-05-01', '1997-06-01', '1997-07-01', '1997-08-01',
  7. '1997-09-01', '1997-10-01', '1997-11-01', '1997-12-01',
  8. '1998-01-01', '1998-02-01', '1998-03-01', '1998-04-01',
  9. '1998-05-01', '1998-06-01']
  10. def active_status(data): #data是df_purchase的一行
  11. status=[]
  12. for i in range(18): #一共有18个月,判断每一个月的消费情况,也可以使用len(df_purchase.columns)
  13. #若本月没有消费
  14. if data[i]==0:
  15. if len(status)>0:#之前有记录
  16. if status[i-1]=='m_unreg': #一直没有注册,看作未注册用户
  17. status.append('m_unreg') #未注册用户
  18. else:
  19. status.append('m_unactive') #这个月没消费,之前消费过
  20. else:#之前没有记录
  21. status.append('m_unreg') #第一个月没有消费,未注册
  22. #若本月消费
  23. else:
  24. if len(status)==0:#之前没有记录
  25. status.append('m_new') #第一次消费
  26. else:#之前有记录
  27. if status[i-1]=='m_unactive':
  28. status.append('m_return') #前几个月不活跃,现在又消费了,回流
  29. elif status[i-1]=='m_unreg':
  30. status.append('m_new') #判断第一次消费
  31. else:
  32. status.append('m_active') #一直在消费
  33. return pd.Series(status,index = col)
  34. pivoted_status = df_purchase.apply(active_status,axis = 1)
  35. #用NaN替代m_unreg,以便后续计算不包含这些数据,未注册不考虑
  36. purchase_stats_ct=pivoted_status.replace({'m_unreg':np.NaN}).apply(lambda x:x.value_counts())
  37. #分层图
  38. purchase_stats_ct.fillna(0).T.plot.area()
  39. #每月活跃情况数量
  40. df_active_level = purchase_stats_ct.T.fillna(0)
  41. #每月活跃情况数量占比
  42. df_active_level_por = pd.DataFrame(purchase_stats_ct.fillna(0).T.apply(lambda x:x/x.sum(),axis = 1))

③复购类指标:每月购买两次以上的客户数/购买一次的客户数

  1. #购买两次以上标为1,一次为0,无购买记录为空
  2. user_df2=pivoted_counts.applymap(lambda x : 1 if x > 1 else np.NaN if x == 0 else 0)
  3. #汇总转置
  4. user_df3 = user_df2.apply(lambda x:x.value_counts()).T
  5. #修改列名
  6. user_df3.columns=['m_buy_one','m_buy_mul']

④回购类指标:回购人数

  1. #某一个时间窗口内消费的用户,在下一个时间窗口仍旧消费的占比。比如,
  2. #我1月消费用户1000,他们中有400个2月依然消费,回购率是40%。
  3. def purchase_return(data):
  4. status=[]
  5. for i in range(17):
  6. if data[i]==1:
  7. if data[i+1]==1:
  8. status.append(1)
  9. if data[i+1]==0:
  10. status.append(0)
  11. else:
  12. status.append(np.nan)
  13. status.append(np.nan) #定义最后一个月的数据
  14. return pd.Series(status,index = col)
  15. pivoted_purchase_return= df_purchase.apply(purchase_return,axis=1)
  16. #占比图
  17. (pivoted_purchase_return.sum() / pivoted_purchase_return.count()).plot(figsize=(10,4))
  18. #复购人数加总
  19. pivoted_purchase_return2 = pd.DataFrame(pivoted_purchase_return.apply(lambda x:x.sum()))
  20. #修改列名
  21. pivoted_purchase_return2.columns=['m_repurchase']

⑤指标合并

  1. df_m_index = pd.merge(pd.merge(pd.merge(df_m_total,df_active_level_por,right_index=True,left_index=True)
  2. ,user_df3,right_index=True,left_index=True),pivoted_purchase_return2,right_index=True,left_index=True)
  3. df_m_index.head()

二、用户维度

消费总额/消费次数/消费量/首次消费时间/最近一次消费时间/消费间隔

  1. df_user = df.pivot_table(index='userid',values=['datetime','products','amounts']
  2. ,aggfunc={'datetime':['max','min'],'products':['sum','count'],'amounts':'sum'})
  3. df_user['gap'] = (df_user['datetime']['max']-df_user['datetime']['min'])/np.timedelta64(1,'D')
  4. df_user.columns=['u_total_amount','u_datetime_max','u_datetime_min','u_total_count','u_total_volumn','u_datetime_gap']
  5. df_user.head()


学习交流,有任何问题还请随时评论指出交流。

基于Python开发数据宽表实例的更多相关文章

  1. TriAquae 是一款由国产的基于Python开发的开源批量部署管理工具

    怀着鸡动的心情跟大家介绍一款国产开源运维软件TriAquae,轻松帮你搞定大部分运维工作!TriAquae 是一款由国产的基于Python开发的开源批量部署管理工具,可以允许用户通过一台控制端管理上千 ...

  2. Sublime Text3介绍和插件安装——基于Python开发

    Subime编辑器是一款轻量级的代码编辑器,是收费的,但是可以无限期使用.官网下载地址:https://www.sublimetext.com. Sublime Text3支持语言开发种类多样,几乎可 ...

  3. scapy - 基于python的数据包操作库

    简介 地址:https://github.com/secdev/scapy scapy是一个基于python的交互式数据包操作程序和库. 它能够伪造或者解码多种协议的数据包,通过使用pcap文件对他们 ...

  4. Django开发密码管理表实例【附源码】

    文章及代码比较基础,适合初.中级人员,高手略过 阅读此篇文章你可以: 获取一个Django实现增删改查的案例源码 了解数据加密的使用场景和方法以及如何在Python3中使用 背景介绍 DBA需要维护一 ...

  5. 基于python开发的股市行情看板

    个人博客: https://mypython.me 近期股市又骚动起来,回忆起昔日炒股经历,历历在目,悲惨经历让人黯然神伤,去年共投入4000元入市,最后仅剩1000多,无奈闭关修炼,忘记股市,全身心 ...

  6. python开发mysql:单表查询&多表查询

    一 单表查询,以下是表内容 一 having 过滤 1.1 having和where select * from emp where id > 15; 解析过程;from > where ...

  7. python开发基础04-列表、元组、字典操作练习

    练习1: # l1 = [11,22,33]# l2 = [22,33,44]# a. 获取内容相同的元素列表# b. 获取 l1 中有, l2 中没有的元素列表# c. 获取 l2 中有, l1 中 ...

  8. 基于python的flask的应用实例注意事项

    1.所有的html文件均保存在templates文件夹中 2.运行网页时python manage.py runserver

  9. Python开发基础-Day3-列表、元组和字典

    列表 列表定义:[]内以逗号分隔,按照索引,存放各种数据类型,每个位置代表一个元素 特性: 1.可存放多个值 2.可修改指定索引位置对应的值,可变 3.按照从左到右的顺序定义列表元素,下标从0开始顺序 ...

随机推荐

  1. linux文件实时同步

    参考博客:https://www.cnblogs.com/MacoLee/p/5633650.html 一.文件同步很简单 服务端:被动的接收传输过来的数据 客户端:主动提供数据给服务端 安装思路:服 ...

  2. STL—— 容器(vector)的各种功能方法

    1. 获取容器的元素个数 size() 使用 vectorName.size() 可以输出这个容器中类型的个数,如下代码: 1 #include <iostream> 2 #include ...

  3. Mac下安装appium+python+Android sdk 环境完整流程

    安装大纲:1,安装jdk (jdk1.8及以上版本都可以,尽量不要用最新可能会不兼容) 2,安装android-sdk (mac版本的android-sdk) 3,mumu模拟器 (随便找的一个) 4 ...

  4. 第二篇:docker 简单入门(二)

    本篇目录 写在最前面的话 最常用的docker命令 获取远程仓库镜像 写在最前面的话 如上图大家看到的这样,以后此类文章请到其他平台查阅,由于博客园提示说,内容太多简单,所以以后简单的内容我会放在cs ...

  5. Unity 黑暗之光 笔记 第三章

    第三章 角色控制   1.创建游戏运行场景并导入素材资源 2.创建和管理标签 1 //const 表明这个是一个共有的不可变的变量 2 public const string ground = &qu ...

  6. 响应式网站设计---Bootstrap

    响应式布局可以帮助我们实现网站布局随屏幕大小自动调整的需求,实现不同屏幕分辨率的终端上浏览网页的不同展示方式,使得网页在PC端和手机端均可以完美的展现其内容,具有自适应性. 使用基于Bootstrap ...

  7. ASP.NET Core 3.1使用log4net/nlog/Serilog记录日志

    Serilog中的结构化日志支持非常好,而且配置简便.我能够比其他任何人更轻松地启动和运行Seirlog.Serilog中的日志可以发送到很多目的地.Serilog称这些东西为"接收器&qu ...

  8. Java学习_Java核心类

    字符串和编码 字符串在String内部是通过一个char[]数组表示的,因此,可以按下面的写法: String s2 = new String(new char[] {'H', 'e', 'l', ' ...

  9. VMware Workstation 16 启动虚拟机失败(vmmon 版本问题)

    问题简述 在 Manjora Linux 下,之前更新过系统,这次启动虚拟机居然就是失败了. 报错信息如下: Version mismatch with vmmon module: expecting ...

  10. intellij idea svn不能更新和提交

    进入设置–version control – subversion如下图,将前边的选项的勾全部去掉,点击ok