开篇
作为万金油式的胶水语言,Python 简直无所不能,在数据迷信畛域的作用更是不可取代。数据分析硬实力中,Python 是一个十分值得投入学习的工具。
这其中,数据分析师用得最多的模块非 Pandas 莫属,如果你曾经在接触它了,无妨一起来通过残缺的数据分析流程,摸索 Pandas 是如何解决业务问题的。
数据背景
为了能尽量多地应用不同的 Pandas 函数,我设计了一个古古怪怪然而理论中又很实在的数据,说白了就是比拟多不标准的中央,等着咱们去荡涤。
数据源是改编自一家超市的订单,文末附文件门路。
导入所需模块
import pandas as pd
数据导入
Pandas 提供了丰盛的数据 IO 接口,其中最罕用的是 pd.read_excel
及pd.read_csv
函数。
data = pd.read_excel('文件门路.xlsx',
sheet_name='分页名称')
data = pd.read_csv('文件门路.csv')
从超市数据集中把多页数据别离导入:
orders = pd.read_excel('超市数据集.xlsx',
sheet_name= '订单表')
customers = pd.read_excel('超市数据集.xlsx',
sheet_name= '客户表')
products = pd.read_excel('超市数据集.xlsx',
sheet_name= '产品表')
该环节除了导入数据外,还须要对数据有初步的意识,明确有哪些字段,及其定义
这里咱们通过 pd.Series.head()
来查看每个数据表格的字段及示例数据
明确业务问题及剖析思路
在业务剖析实战中,在开始剖析之前,须要先明确剖析指标,倒推分析方法、剖析指标,再倒推出所需数据。
这就是「以终为始」的落地思维。
假如业务需要是通过用户分层经营、造成差异化用户经营策略。数据分析师评估后认为可基于 RFM 用户价值模型 对顾客进行分群,并通过不同族群画像特色制订经营策略,比方 重要价值用户属于金字塔顶端人群,须要提供高老本、价值感的会员服务;而个别价值用户属于价格敏感型的虔诚顾客,须要通过折扣刺激生产等。
因而,这里的分析方法则是对存量用户进行 RFM 模型分群,并通过统计各族群数据特色,为业务提供策略倡议。
明确业务需要及分析方法后,咱们能力确定去统计顾客的 R、F、M、以及用于画像剖析的客单价等指标,此时能力进入下一步。
特色工程与数据荡涤
数据迷信中有句话叫 “Garbage In, Garbage Out”,意思是说如果用于剖析的数据品质差、存在许多谬误,那么即便剖析的模型办法再周密简单,都不能变出花来,后果仍是不可用的。
所以也就有了数据科家中 80% 的工作都是在做数据预处理工作的说法。
特色工程次要利用在机器学习算法模型过程,是为使模型成果最佳而进行的系统工程,包含数据预处理 (Data PrePorcessing)、特征提取(Feature Extraction)、特征选择(Feature Selection) 以及特色结构 (Feature Construction) 等问题。
直白地说,能够分成两局部:
- 数据预处理,能够了解成咱们常说的 数据荡涤;
- 特色结构,比方此次构建 RFM 模型及分组用户画像中,R、F、M、客单价等标签就是其对应的特色。
(当然,RFM 非机器学习模型,这里是为了便于了解进行的解释。)
数据荡涤
什么是数据荡涤?
数据荡涤是指找出数据中的「异样值」并「解决」它们,使数据利用层面的论断更贴近实在业务。
异样值:
- 不标准的数据,如空值、反复数据、无用字段等,须要留神是否存在不合理的值,比方订单数据中存在内部测试订单、有超过 200 岁年龄的顾客等
- 特地留神数据格式是否正当,否则会影响表格合并报错、聚合统计报错等问题
- 不合乎业务剖析场景的数据,比方要剖析 2019-2021 年的用户行为,则在此时间段之外的行为都不应该被纳入剖析
如何解决:
- 个别状况下,对于异样值,间接剔除即可
- 但对于数据绝对不多,或该特色比拟重要的状况下,异样值能够通过用平均值代替等更丰盛的形式解决
在理解数据荡涤的含意后,咱们便能够开始用 Pandas 来实操该局部内容。
数据类型
先用 pd.dtypes
来检查数据字段是否正当
发现订单日期、数量是 Object(个别即是字符)类型,前面无奈用它们进行运算,须要通过 pd.Series.astype()
或pd.Series.apply()
办法来批改字符类型
orders['订单日期'] = orders['订单日期'].astype('datetime64')
orders['数量'] = orders['数量'].apply(int)
另外,对工夫类型的解决也能够通过 pd.to_datetime
进行:
orders['订单日期'] = pd.to_datetime(orders['订单日期'])
批改字段名
经验丰富的数据分析师发现字段名字也有问题,订单 Id
存在空格不便于前面的援用,须要通过 pd.rename()
来批改字段名
orders = orders.rename(columns={'订单 Id':'订单 ID',
'客户 Id':'客户 ID',
'产品 Id':'产品 ID'})
customers = customers.rename(columns={'客户 Id':'客户 ID'})
多表连贯
把字段名以及数据类型解决好后,就能够用 pd.merge
将多个表格进行连贯。
表连贯中的 on
有两种形式,一种是两个表用于连贯的字段名是雷同的,间接用 on
即可,如果是不雷同,则要用 left_on, right_on
进行。
data = orders.merge(customers, on='客户 ID', how='left')
data = data.merge(products, how='left',
left_on='产品 ID', right_on='物料号')
剔除多余字段
对于第二种状况,失去的表就会存在两列雷同含意但名字不同的字段,须要用 pd.drop
剔除多余字段。此外,“行 Id”在这里属于无用字段,一并剔除掉。
data.drop(['物料号','行 Id'],axis=1,
inplace=True)
调整后失去的表构造:
文本处理——剔除不合乎业务场景数据
依据业务教训,订单表中可能会存在一些内部测试用的数据,它们会对剖析论断产生影响,须要把它们找进去剔除。与业务或运维沟通后,明确测试订单的标识是在“产品名称”列中带“测试”的字样。
因为是文本内容,须要通过 pd.Series.str.contains
把它们找到并剔除
data = data[~data['产品名称'].str.contains('测试')]
工夫解决——剔除非剖析范畴数据
影响消费者的因素具备工夫窗口递加的个性,例如你 10 年前买了顶可可恶爱的帽子,不代表你明天还须要可可恶爱格调的产品,因为 10 年工夫足以让你产生许多扭转;然而如果你 10 天以前才买了田园风的裙子,那么就能够置信你当初还会喜爱田园风产品,因为你偏好的格调在短期内不会有太大扭转。
也就是说,在用户行为剖析中,行为数据具备肯定时效 ,因而须要联合业务场景明确工夫范畴后,再用pd.Series.between()
来筛选近合乎工夫范畴的订单数据进行 RFM 建模剖析。
data= data[data['订单日期'].between('2019-01-01','2021-08-13')]
特色结构
此环节目标在于结构分析模型,也就是 RFM 模型及分群画像剖析所需的特色字段。
数据聚合——顾客生产特色
首先,是 RFM 模型中顾客的生产特色:
- R:客户最近一次购买离剖析日期 (设为 2021-08-14)的间隔,用以判断购买用户沉闷状态
- F:客户生产频次
- M:客户生产金额
这些都是一段时间内生产数据的聚合,所以能够用 pd.groupby().agg()
实现
consume_df = data.groupby('客户 ID').agg(累计生产金额 =('销售额',sum),
累计生产件数 =('数量',sum),
累计生产次数 =('订单日期', pd.Series.nunique),
最近生产日期 =('订单日期',max)
)
其中,R 值比拟非凡,须要借用 datetime 模块,计算日期之间的间隔
from datetime import datetime
consume_df['休眠天数'] = datetime(2021,8,14) - consume_df['最近生产日期']
consume_df['休眠天数'] = consume_df['休眠天数'].map(lambda x:x.days)
计算所得顾客累计生产数据统计表:
分箱解决——客单价区间划分
依据后面剖析思路所述,实现 RFM 模型用户分群后,还要统计各族群用户生产画像,这里因篇幅限度仅统计各族群 客单价散布 特色。
此时,计算完客单价数据后,须要用 pd.cut
对客单价进行分箱操作,造成价格区间。
consume_df['客单价'] = consume_df['累计生产金额']/consume_df['累计生产次数']
consume_df['客单价区间'] = pd.cut(consume_df['客单价'],bins=5)
通过 pd.Series.value_counts
办法统计客单价区间散布状况:
pd.cut
中的 bins 参数为将客单价划分的区间数,填入 5,则均匀分为 5 档。当然,还是那句话,这个在实操中须要与业务明确,或联合业务场景确定。
RFM 建模
实现数据荡涤及特色结构后,就进入到建模剖析环节。
Tukey’s Test 离群值检测
依据剖析教训,离群值会极大地对统计指标造成影响,产生较大误差,例如把马云放到你们班里,计算得出班级均匀资产上百亿。在这里,马云就是离群值,要把它剔除进来。
所以,在开始对 RFM 阈值进行计算之前,有必要先对 R、F、M 的值进行离群值检测。
这里咱们用Turkey’s Test 办法,简略来说就是通过分位数之间的运算造成数值区间,将在此区间之外的数据标记为离群值。不分明的同学能够知乎搜一下,这里不开展讲。
Turkey’s Test 办法依赖分位数的计算,在 Pandas,通过 pd.Series.quantile
计算分位数
def turkeys_test(fea):
Q3 = consume_df[fea].quantile(0.75)
Q1 = consume_df[fea].quantile(0.25)
max_ = Q3+1.5*(Q3-Q1)
min_ = Q1-1.5*(Q3-Q1)
if min_<0:
min_ =0
return max_, min_
以上代码实现了 Tukey’s Test 函数,其中 Q3 就是 75 分位、Q1 就是 25 分位。而 min_ 和 max_则造成正当值区间,在此区间之外的数据,不管太高还是太低还是离群值。
留神,在这里因为存在 min_是正数的状况,而生产数据不可能是正数,所以补充了一个把转为 0 的操作。
接下来,给 RFM 特色数据表新增字段 ” 是否异样 ”,默认值为 0,而后再用 Tukey’s Test 函数把异样数据标记为 1,最初只需保留值为 0 的数据即可。
consume_df['是否异样'] = 0
for fea in rfm_features:
max_, min_= turkeys_test(fea)
outlet = consume_df[fea].between(min_,max_) #bool
consume_df.loc[~outlet,'是否异样']=1
consume_df = consume_df[consume_df['是否异样']==0]
聚类与二八准则——RFM 阈值计算
当初曾经能够确保建模所用的特色是无效的,此时就须要计算各指标阈值,用于 RFM 建模。阈值的计算个别通过聚类算法进行,但这里不波及机器学习算法。从实质上讲,聚类后果通常是合乎二八准则的,也就是说重要客群应该只占 20%,所以咱们能够计算 80 分位数来近似作为 RFM 模型阈值。
M_threshold = consume_df['累计生产金额'].quantile(0.8)
F_threshold=consume_df['累计生产次数'].quantile(0.8)
R_threshold = consume_df['休眠天数'].quantile(0.2)
RFM 模型计算
失去 RFM 阈值后,即可将顾客的 RFM 特色进行计算,超过阈值的则为 1,低于阈值的则为 0,其中 R 值计算逻辑相同,因为 R 值是休眠天数,数值越大反而代表越不沉闷。
consume_df['R'] = consume_df['休眠天数'].map(lambda x:1 if x<R_threshold else 0)
consume_df['F'] = consume_df['累计生产次数'].map(lambda x:1 if x>F_threshold else 0)
consume_df['M'] = consume_df['累计生产金额'].map(lambda x:1 if x>M_threshold else 0)
对顾客 RFM 特色划分 1 和 0,即高与低后,即可进行分群计算:
consume_df['RFM'] = consume_df['R'].apply(str)+'-' + consume_df['F'].apply(str)+'-'+ consume_df['M'].apply(str)
rfm_dict = {
'1-1-1':'重要价值用户',
'1-0-1':'重要倒退用户',
'0-1-1':'重要放弃用户',
'0-0-1':'重要挽留用户',
'1-1-0':'个别价值用户',
'1-0-0':'个别倒退用户',
'0-1-0':'个别放弃用户',
'0-0-0':'个别挽留用户'
}
consume_df['RFM 人群'] = consume_df['RFM'].map(lambda x:rfm_dict[x])
至此,已实现 RFM 建模及用户分群计算。
分群画像
实现模型分群后,就要对各族群别离统计人数及客单价散布。
人数占比
最简略的一个画像剖析,则是用 pd.Series.value_counts
对各族群进行人数统计,剖析绝对占比大小。
rfm_analysis = pd.DataFrame(consume_df['RFM 人群'].value_counts()).rename(columns={'RFM 人群':'人数'})
rfm_analysis['人群占比'] = (rfm_analysis['人数']/rfm_analysis['人数'].sum()).map(lambda x:'%.2f%%'%(x*100))
透视表
各族群客单价散布波及多维度剖析,能够通过 Pandas 透视性能 pd.pivot_table
实现
代码中,聚合函数 aggfunc 我用了 pd.Series.nunique
办法,是对值进行去重计数的意思,在这里就是对客户 ID 进行去重计数,统计各价位段的顾客数。
pd.pivot_table(consume_df.reset_index(), # DataFrame
values='客户 ID', # 值
index='RFM 人群', # 分类汇总根据
columns='客单价区间', # 列
aggfunc=pd.Series.nunique, # 聚合函数
fill_value=0, # 对缺失值的填充
margins=True, # 是否启用总计行 / 列
dropna=False, # 删除缺失
margins_name='All' # 总计行 / 列的名称
).sort_values(by='All',ascending=False)
这样就失去了每个族群在不同价位段上的散布,配合其余维度的画像剖析能够进一步造成营销策略。
逆透视表
最初,做个骚操作,就是透视后的表属于多维度表格,但咱们要导入到 PowerBI 等工具进行可视化剖析时,须要用 pd.melt
将它们逆透视成一维表。
pivot_table.melt(id_vars='RFM 人群',
value_vars=['(124.359, 3871.2]', '(3871.2, 7599.4]',
'(7599.4, 11327.6]', '(11327.6, 15055.8]',
'(15055.8, 18784.0]']).sort_values(by=['RFM 人群','variable'],ascending=False)
这样字段名为 ” 人群 ”、” 指标 ”、” 值 ” 的表格,能够一行就把信息出现的表格就是一维表。而后面各族群人数统计中,须要一行一列来定位信息的就是二维表。
结尾
至此,咱们曾经通过 Pandas 建设了 RFM 模型及分组人群画像剖析,实现了业务剖析需要。
受限于篇幅,本文仅对数据分析过程中 Pandas 高频应用的函数办法进行了演示,同样重要的还有整个剖析过程。如果其中对某些函数不相熟,激励同学多利用知乎或搜索引擎补充学习。同时也欢送加饼干哥哥微信探讨。
更多 Pandas 函数应用阐明,可查问中文文档
本文算是数据分析流程的根底篇,打算会再整顿一份 进阶篇,波及机器学习流程、以及更多特色工程内容,同样会以业务落地实战的形式进行介绍。