这个烂大街的用户消费分析案例,我用了点不一样的pandas技巧

2021-09-01 12:11:23 浏览数 (1)

更多 Python 数据处理的干货,敬请关注!!!!

发现许多小伙伴入门Python几个月,还是低效率做数据处理。这套课程以形象的示意图,精心安排的案例,循序渐进带你玩转数据处理分析神器——pandas,课程中还有分析案例噢,干货满满!

前言

这是一个关于在线音乐零售平台的用户消费分析案例,在网上到处可见,听闻不少培训机构也用于数据分析案例。我大概看了一些其他的文章,基本是千篇一律。

如果我今天也用同一个思路"水"一篇文章就没有多大意思。因此,这次我会分享一些你可能极少看到的一种 pandas 的代码组织方式,我相信你会有所收获。

你可以网上搜索"用户消费分析 pandas" 查阅其他同类文章作为对比学习


数据背景

案例数据为 CDNow 平台上某段时间的订单数据,定义加载数据的函数:

  • 行3:数据源是文本文件,每列数据由多个空格分隔,因此我们使用 pd.read_table 方法,其中参数 sep 设置正则表达式"s " 表示1个或多个连续的空格

显示数据:

  • 信息有用户id,日期,购买数量和购买金额

数据加载环节比较重要的3点:

  1. 清楚数据颗粒
  2. 缺失值处理
  3. 正确的字段类型

注意数据颗粒为"每天每一笔订单的信息"

因此,完全有可能出现同一天同一个用户多笔的记录:


现在看看数据表基本信息:

  • 上方红框信息,表明共 6万多接近7万行的数据
  • 下方红框信息,表明4个列没有缺失数据
  • 绿色框,看到 user_id 与 date 的类型不对

转换类型的逻辑我写在加载数据的函数中:

  • 行6:使用 pd.to_datetime 把非日期类型的字段转为日期,format 定义了提取规则

重新执行加载数据后即可


数据异常

数据分析并非拿到数据后马上做各种指标统计,做图表。如果数据本身出现逻辑错误,就算你的图表做得再漂亮也没用。

因此,pandas 为数据表做了一个方法,快速列出每一列的常用统计信息:

  • DataFrame.describe 列出数值类的字段的统计信息,参数 include='all' ,让统计所有的列
  • 我们特别要关注上图红框的列,能看出一些基本信息与问题
  • 订单时间范围从1997年1月到1998年6月
  • 金额最小值为0,这是赠品?
  • 平均消费(金额)为35左右,但最大值有1286!
  • 购买数据最大值为99!
  • 数量列与金额列的中位数低于均值,可以大致得知大部分用户的消费与购买数量都在均值以下

看看购买数量高于70的记录:

  • 原来那笔最高金额就在这里

这不能看出啥问题,看看这些用户平时的消费:

  • 感觉与平时的消费习惯不符

从绝对数量和金额来看,有点与他们的消费习惯不符合。

不妨从单价上看看情况:

  • 行6:通过订单金额除以数量,求出单价
  • 从单价上看,2笔高购买数量的订单的单价都在各自用户的平均范围内

这里我们就暂且保留他们。

是否保留这些异常数据,可能需要更多其他维度的数据辅助判断。

不过在这里,你也可以独立思考其他的方式做判断,这通常需要结合业务知识。

比如,看看以上2笔数据的所在日期附近,是否有其他用户也出现购买数量上的明显提升。

这可能是那段时间搞促销,或某明星出新专辑,有粉丝大量购买。

这里不再展开


再看看订单金额为0的情况:

  • 共80笔消费金额为0的记录

啰嗦的汇总代码

数据分析中的数据处理操作,大部分集中在分组统计中,因为需要变换数据颗粒做统计运算。

我们随意看几个例子。

"整体每月的销售额趋势":

  • 眼瞎也能看出 97年4月的销售额出现大幅下降

销售额的下降有各种可能:

  1. 消费人数减少
  2. 消费金额减少(客单价)
  3. 一开始搞促销吸引大量顾客,促销后出现逆转

一个个来看看。

"那么每个月的消费人数走势如何呢":

  • 注意数据颗粒是订单,统计人数时是不能直接对记录计数,如果同一个人在分组范围内出现多笔,应该视为一笔,因此需要对 user id 去重后再计数。这就是这里用 nunique 的原因
  • 注意3月份的消费人数减少,但实际上本月的销售额是上升的

"看看我们的顾客的消费能力吧":

  • 用销售额除以顾客人数,得到每个顾客的消费价格
  • 可以看到,其实顾客的消费能力一直在上升
  • 为什么3月的购买人数减少的情况下,销售额仍然有所提升?这里可以看出一些端倪。这时候出现了高价值的顾客

"那么是不是真的一开始搞促销才有大量客户来购买?":

  • 也不是那么一回事,平均订单单价也是在下降(我们的数据没有商品信息,只能这么来看看)

分析过程不是本文重点,毕竟大家不一定对零售或电商行业有兴趣。

上面的过程展示了 pandas 的灵活和便捷。但是有没有发现这些代码比较难以表达业务。

比如,统计顾客人数的时候,我们用了两种不同的写法:

其次,客单价的计算表达也很奇怪:

  • 金额除以 user_id !这也太傻了

如果你曾经使用过 BI 软件的话,你会发现这些软件的使用思维与我们上述的代码思维不太一样。

他们首先需要我们定义各种度量,一般是基于数据源的指标列的一种计算。

比如,我们求销售总额,只需要定义"使用 amount 字段,统计方式为 求和" 即可:

代码语言:javascript复制
agg_消费总额 = {'amount': 'sum'}

其次我们也可以把常用的分组依据集中定义:

代码语言:javascript复制
gk_按月 = pd.Grouper(key='date', freq='M')

现在统计销售额趋势是这样子:

不过,我们注意到,统计后的结果列名不受我们控制,因此,在 pandas 0.25版本追加了一个新的聚合方式,我们现在这样子定义度量:

代码语言:javascript复制
agg_消费总额 = {'消费总额': pd.NamedAgg('amount', 'sum')}
  • 字段的key 是结果的列名,value 是一个 pd.NamedAgg 对象,其中的参数分别是列名与统计方法

调用如下:

  • 注意此时我们需要解包操作,把其中定义的字典解开为参数传入

现在可以一次性定义需要用到的指标度量:

其次把指标计算也定义出来:

  • 有些计算如果觉得不希望每次统计都重新计算,你可以在数据源加载后立刻执行即可生成即可

现在重新执行刚刚的4个分析过程,就变得简单直白了。

"每月的销售额":

"每月消费人数":

"每月客单价":

  • 行3:多个度量,只需要分别传入即可

"每月平均订单单价":

本次涉及的并非一些 pandas 的方法,而是使用 pandas 的一种模式,常用于数据探索分析。

本文讲解的度量值定义看似只能在单个项目中使用,实际只需要稍微思考一下,就能定义出跨项目通用的度量值统计方式。

这才是 pandas 的价值所在,否则我们直接使用其他的 BI 软件就可以了。

更多更详细的 pandas 高级应用,请关注我的 pandas 专栏,里面会有这些技巧的所有详细讲解和案例


最后

你会发现我源码中定义了其他的度量值,这会在后续更复杂的分析时用到,下次就会讲到。敬请关注!

0 人点赞