目录
- 一、电商用户分析
- 1、数据字段信息
- 2、数据读取
- 3、数据清洗
- 4、可视化分析
- 1、每年销售额的增长情况
- 2、各个地区分店的销售额
- 3、每个分店每一年的销售额
- 4、销售淡旺季
- 5、新增用户
- 二、RFM 模型
- 1、RFM 模型的三个维度
- 2、RFM 的客户类型标签
- 3、RFM 模型的二分法思想
- 4、代码
一、电商用户分析
1、数据字段信息
字段 | 说明 |
---|---|
RowID | 行编号 |
OrderID | 订单 ID |
OrderDate | 订单日期 |
ShipDate | 发货日期 |
ShipMode | 发货模式 |
CustomerID | 客户 ID |
CustomerName | 客户姓名 |
Segment | 客户类别 |
City | 客户所在城市 |
State | 客户所在州 |
Country | 客户所在国家 |
PostalCode | 邮编 |
Market | 商店所属区域 |
Region | 商店所属州 |
ProductID | 产品 ID |
Category | 产品类别 |
Sub-Category | 产品子类别 |
ProductName | 产品名称 |
Sales | 售价 |
Quantity | 销售量 |
Discount | 折扣 |
Profit | 利润 |
ShippingCost | 发货成本 |
OrderPriority | 订单优先级 |
2、数据读取
import pandas as pd # 导入 Pandas 库并使用别名 pd
# 读取 CSV 文件,使用 gbk 编码
data = pd.read_csv(r'F:\data\dataset.csv', encoding='gbk')
print(data)
# 打印数据的列名
print(data.columns)
# 重新命名数据的列名
data.columns = ['行编号', '订单ID', '订单日期', '发货日期', '发货模式', '客户ID', '客户姓名', '客户类别', '客户所在城市', '客户所在州', '客户所在国家', '邮编', '商店所属区域', '商店所属州', '产品ID', '产品类别', '产品子类别', '产品名称', '售价', '销售量', '折扣', '利润', '发货成本', '订单优先级']
print(data.head())
3、数据清洗
# 打印数据的基本信息
data.info()
# 1、发货日期 - 订单日期 >= 0,异常的数据 < 0
# 将 '发货日期' 和 '订单日期' 列的数据类型转换为 datetime
data['发货日期'] = pd.to_datetime(data['发货日期'])
data['订单日期'] = pd.to_datetime(data['订单日期'])
# 计算 '发货秒数' 列,表示发货日期与订单日期的时间差(秒)
data['发货秒数'] = (data['发货日期'] - data['订单日期']).dt.total_seconds()# 删除发货日期早于订单日期的
data.drop(index=data[data['发货秒数'] < 0].index, inplace=True) # drop() 这里是按索引删除
print(data.head())
# 打印数据的形状
print(data.shape) # (51097, 25)
# 2、删除售价为负数据(异常数据)
# 查找 '售价' 列小于 0 的行
print(data[data['售价'] < 0])
# 没有售价为负的,不用处理
# 打印数据的信息
data.info()
# 3、查看空值,重复值
# 打印每列的缺失值数量
print(data.isnull().sum())
# 计算 '行编号' 列的唯一值数量
print(data['行编号'].unique().size) # 51094
# 删除重复的 '行编号' 行(去重)
data.drop_duplicates('行编号', inplace=True)
data.info()
# 清洗 '发货模式'
# 打印 '发货模式' 列的缺失值数量
print(data['发货模式'].isnull().sum()) # 11
# 打印 '发货模式' 列的众数(出现次数最多的)
print(data['发货模式'].mode())
# 0 Standard Class
# dtype: object
# 打印 '发货模式' 列的类型
print(type(data['发货模式'].mode()))
# <class 'pandas.core.series.Series'># 用众数填充 '发货模式' 列的缺失值
data['发货模式'].fillna(value=data['发货模式'].mode()[0], inplace=True)
# 打印 '发货模式' 列的缺失值数量
print(data['发货模式'].isnull().sum()) # 0
# 删除 '邮编' 列(缺失多且对本次分析无用)
data.drop(columns=['邮编'], inplace=True)
data.info()
# 打印数据的描述统计信息
print(data.describe())
# 清洗 '折扣'
# 查找 '折扣' 列大于 1 的行
print(data[data['折扣'] > 1])
# 将 '折扣' 列大于 1 的值替换为 None
data['折扣'] = data['折扣'].mask(data['折扣'] > 1, None)
# 用 '折扣' 列的均值填充缺失值
data['折扣'].fillna(value=round(data['折扣'].mean(), 2), inplace=True)
# 打印数据的描述统计信息
print(data.describe())
# 清洗 '订单日期'
# 添加 '下订单年'、'下订单月' 和 '下订单季度' 列
data['下订单年'] = data['订单日期'].dt.year
data['下订单月'] = data['订单日期'].dt.month
data['下订单季度'] = data['订单日期'].dt.to_period('Q')
print(data.head())
# 查找重复的行数
print(data.duplicated().sum()) # 0
4、可视化分析
1、每年销售额的增长情况
# 创建一个新的列'销售额',计算售价与销售量的乘积,表示销售额
data['销售额'] = data['售价']*data['销售量']
# 打印数据的前几行,用于查看新增的销售额列
print(data.head())
# 根据'下订单年'列分组,计算每年的销售额总和
sales_year = data.groupby('下订单年')['销售额'].sum()
# 打印每年的销售额总和
print(sales_year)
# 下订单年
# 2011 1.110551e+07
# 2012 1.290868e+07
# 2013 1.667801e+07
# 2014 2.090141e+07
# Name: 销售额, dtype: float64
# 计算每年的销售额增长率,分别以2012年、2013年、2014年为基准年
sales_year_12 = (sales_year[2012]/sales_year[2011]) -1
sales_year_13 = (sales_year[2013]/sales_year[2012]) -1
sales_year_14 = (sales_year[2014]/sales_year[2013]) -1
# 打印销售额增长率
print(sales_year_12, sales_year_13, sales_year_14)
# 0.16236705386979122 0.29200004761249243 0.2532315853953533
# 创建一个包含年销售额和订单增长率的数据框
sales_rate = pd.DataFrame({'年销售额':sales_year,'订单增长率':[0, sales_year_12, sales_year_13, sales_year_14]
})
# 打印包含销售额和增长率的数据框
print(sales_rate)
import matplotlib.pyplot as plt # 导入 Matplotlib 库
# 设置字体为中文黑体
plt.rcParams['font.family'] = 'SimSun'# 准备绘图所需的数据
x = [str(value) for value in sales_rate.index.tolist()] # 把数值转成字符串
# 两个 y 轴数据差距很大,但又要画在同一个图里.可以使用双 y 轴
y1 = sales_rate['年销售额']
y2 = sales_rate['订单增长率']# 创建一个包含两个子图的图表,并设置图表大小
fig = plt.figure(figsize=(10,6))
# 新建子图1
ax1 = fig.add_subplot(1,1,1)
# ax2 与 ax1 共享 x 轴
ax2 = ax1.twinx()# 绘制柱状图表示年销售额
ax1.bar(x, y1, color='blue', label='年销售额')# 绘制折线图表示年增长率
ax2.plot(x, y2, marker='*', color='r', linewidth=3, markersize='10', label='年增长率')# 添加x轴标签
ax1.set_xlabel('年份', fontsize=20)
ax1.set_ylabel('年销售额', fontsize=20)
ax2.set_ylabel('年增长率', fontsize=20)# 设置刻度
ax1.tick_params(axis='x', labelsize=15)
ax1.tick_params(axis='y', labelsize=15)
ax2.tick_params(axis='y', labelsize=15)# 设置图例位置和外边界框
ax1.legend(loc='upper right', bbox_to_anchor=(1.25, 1))
ax2.legend(loc='upper right', bbox_to_anchor=(1.25, 1.08))# 显示图表
plt.show()
结论:
年销售额逐年递增。
2、各个地区分店的销售额
# 打印数据的前几行,用于查看数据的整体情况
print(data.head())
# 打印数据的基本信息,包括列的数据类型和非空值数量
data.info()
# 根据'商店所属区域'列分组,计算各区域的销售额总和
sales_area = data.groupby('商店所属区域')['销售额'].sum()
# 打印各区域的销售额总和
print(sales_area)
# 绘制销售额占比的饼图,以百分比形式显示,设置标题和字体大小,以及图表大小
sales_area.plot(kind='pie', autopct='%1.1f%%', title='2011年-2014各分店销售额占比', fontsize=15, figsize=(10,10))
# 显示图表
plt.show()
结论:
APAC 分店销售额占比最高,近1/3。
3、每个分店每一年的销售额
# 打印数据的基本信息,包括列的数据类型和非空值数量
data.info()
# 使用数据透视表,根据'商店所属区域'和'下订单年',计算不同地区每年的销售额总和
sales_area2 = pd.pivot_table(data, index='商店所属区域', columns='下订单年', values='销售额', aggfunc='sum')
# 打印不同地区每年销售额的数据透视表
print(sales_area2)
# 绘制柱状图,对比2011年-2014年不同地区每年的销售额
sales_area2.plot(kind='bar', title='2011年-2014年不同地区每年销售额对比', figsize=(10, 6), fontsize=15)
# 显示图表
plt.show()
结论:
销售额逐年增长。
4、销售淡旺季
# 使用数据透视表,根据'下订单月'和'下订单年',计算每年每月的销售额总和
sales_year_month = pd.pivot_table(data, index='下订单月', columns='下订单年', values='销售额', aggfunc='sum')
# 打印每年每月销售额的数据透视表
print(sales_year_month)
# 绘制折线图,显示每年每月的销售额趋势,并添加图例
sales_year_month.plot(fontsize=15, figsize=(10, 6)).legend(fontsize=15)
# 显示图表
plt.show()
结论:
旺季 6月和11月,淡季 2月 4月 7月。
5、新增用户
# 求每年每月的新增用户数
# 复制原始数据,以便后续分析客户相关信息
data_customer = data.copy()
# print(data_customer)# 新用户,第一次购买,对用户进行去重
# 根据'客户ID'去重,保留第一次出现的记录
data_customer = data_customer.drop_duplicates(subset='客户ID')
# print(data_customer)# 按年按月分组聚合
# 使用数据透视表,根据'下订单月'和'下订单年',计算每年每月不同客户的数量
customer_year_month = pd.pivot_table(data_customer, index='下订单月', columns='下订单年', values='客户ID', fill_value=0, aggfunc='count')
# 打印每年每月不同客户的数量的数据透视表
print(customer_year_month)
二、RFM 模型
1、RFM 模型的三个维度
Recency(最近购买时间):
这个维度衡量客户最近一次购买的时间,通常以天数来表示。较短的 Recency 值表示客户最近有过购买行为,而较⻓的 Recency 值则表示客户离上次购买较远。Recency 的分析有助于识别哪些客户是“活跃客户”。
Frequency(购买频率):
这个维度衡量客户在一定时间内的购买次数。购买频率高的客户可能更容易进行再营销活动,因为他们已经展现出对产品或服务的兴趣和忠诚度。
Monetary(购买金额):
这个维度衡量客户在一定时间内的总购买金额。购买金额高的客户可能是企业的高价值客户,因此在市场营销活动中可能需要特别关注和激励这一群体。
2、RFM 的客户类型标签
R | F | M | 客户类型 |
---|---|---|---|
0 | 1 | 1 | 重要价值客户 |
1 | 1 | 1 | 重要唤回客户 |
0 | 0 | 1 | 重要深耕客户 |
1 | 0 | 1 | 重要挽留客户 |
0 | 1 | 0 | 潜力客户 |
1 | 1 | 0 | 一般维持客户 |
0 | 0 | 0 | 新客户 |
1 | 0 | 0 | 流失客户 |
3、RFM 模型的二分法思想
Recency(最近购买时间):
- R1:最近购买时间较短的客户
- R2:最近购买时间较⻓的客户
Frequency(购买频率):
- F1:购买频率较高的客户
- F2:购买频率较低的客户
Monetary(购买金额):
- M1:购买金额较高的客户
- M2:购买金额较低的客户
界定某一数据被分在哪个区间,这里采用平均值来实现,即大于平均值,被分为一类,小于平均值被分为另一类。至于等于平均值,被归于哪一类,实际归到哪一类都可以,只需保证所有数据使用相同的规则即可。
4、代码
# 打印数据集的形状
print(data.shape) # (51094, 28)
# 输出数据集的信息
data.info()
# 筛选出 '下订单年' 列为 2014 年的数据
data_14 = data[data['下订单年'] == 2014]
# 打印筛选后的数据集
print(data_14)
# 复制筛选后的数据集
customerdf = data_14.copy()
# 打印复制后的数据集
print(customerdf)
# 在复制的数据集中新增一列 '订单数',并将其初始化为 1
customerdf['订单数'] = 1
# 打印修改后的数据集的前几行
print(customerdf.head())
# 使用 pivot_table 计算 RFM 指标,包括最近购买日期、总订单数和总销售额
rfmdf = customerdf.pivot_table(index='客户ID',values=['订单日期', '订单数', '销售额'],aggfunc={'订单日期': 'max', '订单数': 'sum', '销售额': 'sum'})
# 打印 RFM 指标表
print(rfmdf)
# 计算最近购买日期距离当前日期的天数,添加一列 'R'
# 把所有交易记录数据里最晚的交易时间看成是现在当前时间
rfmdf['R'] = (rfmdf['订单日期'].max() - rfmdf['订单日期']).dt.days
# 打印添加 'R' 列后的 RFM 指标表
print(rfmdf)
# 重命名列名为 'R'、'F' 和 'M'
rfmdf.rename(columns={'订单数': 'F', '销售额': 'M'}, inplace=True)
# 打印重命名后的 RFM 指标表
print(rfmdf)
# 仅保留 'R'、'F'、'M' 列
rfmdf = rfmdf[['R', 'F', 'M']]
# 打印最终的 RFM 指标表
print(rfmdf)
# 定义函数 rfm_func,根据 RFM 的值给客户打标签,并创建新列 '用户标签'
def rfm_func(x):level = x.apply(lambda x: '1' if x > 0 else '0')label = level['R'] + level['F'] + level['M']d = {'011': '重要价值客户','111': '重要唤回客户','001': '重要深耕客户','101': '重要挽留客户','010': '潜力客户','110': '一般维持客户','000': '新客户','100': '流失客户'}return d[label]
# 应用 rfm_func 函数,创建 '用户标签' 列
rfmdf['用户标签'] = rfmdf.apply(lambda x: x - x.mean()).apply(rfm_func, axis=1)
# 打印添加 '用户标签' 列后的 RFM 指标表
print(rfmdf)
import matplotlib.pyplot as plt # 导入 Matplotlib 库
# 设置字体为中文黑体
plt.rcParams['font.family'] = 'SimSun'
plt.style.use('fivethirtyeight')
rfmdf['用户标签'].value_counts().plot.bar(figsize=(20, 9), fontsize=15)
plt.show()
记录学习过程,欢迎讨论交流,尊重原创,转载请注明出处~