案例分析: 电商交易数据分析

案例分析练习:

电商交易数据分析
# 加载数据分析需要使用的库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

一、首先明确分析的目标

1、加载数据文件,以id列为索引

  • 使用read_csv方法加载csv数据文件,默认分隔符是逗号
# 加载数据,加载之前先用文本编辑器看下数据格式,首行是什么,分隔符是什么的
df = pd.read_csv('order_info_2016.csv',index_col='id')

2、查看下数据文件头部信息

df.head()

案例分析: 电商交易数据分析_第1张图片
3、使用describe和info方法看下数据的大概分布

# 加载好数据之后,第一步先分别使用describe和info方法看下数据的大概分布
# 这两个方法放到两个cell中
df.describe()

案例分析: 电商交易数据分析_第2张图片

  • 加载设备类型device_type
# 加载device_type
device_type = pd.read_csv('device_type.txt')
device_type

案例分析: 电商交易数据分析_第3张图片

  • 查看索引、数据类型和内存信息
df.info()

案例分析: 电商交易数据分析_第4张图片

二、对数据进行清洗

1、首先要做一个数据的清洗,order_id在一个系统里是唯一值

# 先看下有没有重复值
# 注意:当我们对一列取size属性的时候,返回的是行数,如果对于dataframe使用size,返回的是行乘以列的结果,也就是总的元素数
df.orderId.unique().size

案例分析: 电商交易数据分析_第5张图片
注意:当我们对一列取size属性的时候,返回的是行数,如果对于dataframe使用size,返回的是行乘以列的结果,也就是总的元素数

  • 如果有重复值,我们一般最后处理,因为其他的列可能会影响到删除哪一条重复的记录,先处理其他的列。

2、userId我们只要从上面的describe和info看下值是不是在正常范围就行了

# 对于订单数据,一个用户有可能有多个订单,重复值是合理的
df.userId.unique().size

3、productId最小值是0,先来看下值为0的记录数量

# productId
# productId最小值是0,先来看下值为0的记录数量
df.productId[(df.productId == 0)].size

在这里插入图片描述

  • 177条记录,数量不多,可能是因为商品的上架下架引起的,处理完其他值的时候我们再把这些删掉

3、cityId类似于userId,值都在正常范围,不需要处理

# cityId类似于userId,值都在正常范围,不需要处理
df.cityId.unique().size

在这里插入图片描述
4、price没有空值,且都大于0,注意单位是分,我们要把它变成元

# price没有空值,且都大于0,注意单位是分,我们把它变成元
df.price = df.price /100
df.price

案例分析: 电商交易数据分析_第6张图片
5、payMoney有负值,我们下单不可能是负值,所以这里对于负值的记录要删除掉

# 展示负值的记录
df[df.payMoney < 0 ]

案例分析: 电商交易数据分析_第7张图片

  1. 使用drop方法删除负值的记录
# 删除负值的记录
df.drop(index=df[df.payMoney < 0].index, inplace=True)
  1. 检查看下,是否删除成功
# 在看下,已经没有了
df[df.payMoney < 0].index

在这里插入图片描述
3. 将payMoney 列数据变成元为单位

# 变成元
df.payMoney = df.payMoney / 100
df.payMoney

案例分析: 电商交易数据分析_第8张图片
6、channelId根据info的结果,有些null的数据,可能是端的bug等原因,在下单的时候没有传channelId字段。
数据量大的时候,删掉少量的null记录不会影响统计结果,这里我们直接删除

# 展示null记录
df[df.channelId.isnull()]

案例分析: 电商交易数据分析_第9张图片
4. 使用drop方法删除空值的记录

# 删除
df.drop(index=df[df.channelId.isnull()].index, inplace=True)
  1. 检查看下是否删除成功
# 在查看
df[df.channelId.isnull()]

在这里插入图片描述
7、deviceType的取值可以看device_type.txt文件,没有问题,不需要处理。

8、使用 df.isnull() 我们观察到,createTime和payTime都没有null, 不过我们是要统计2016年的数据,所以把非2016年的删掉; payTime类似,这里只按创建订单的时间算,就不做处理了

  • 先把createTime和payTime转换成datetime格式
# 先把createTime和payTime转换成datetime格式
df.createTime = pd.to_datetime(df.createTime)
df.payTime = pd.to_datetime(df.payTime)
df.dtypes

案例分析: 电商交易数据分析_第10张图片

  • 引用处理datetime时间模块,并设置2016年的时间区域
import datetime
startTime = datetime.datetime(2016, 1, 1)
endTime = datetime.datetime(2016, 12, 31, 23,59, 59)
# 有16年之前的数据,需要删掉
df[df.createTime < startTime]

案例分析: 电商交易数据分析_第11张图片

  • 删除16年之前的数据
df.drop(index=df[df.createTime < startTime].index, inplace=True)
  • 验证是否删除
df[df.createTime < startTime]
  • 处理16年之后的数据
# 处理16年之后的数据
df[df.createTime > endTime]
  • 看下支付时间有没有16年以前的,支付时间在16年之后的这里就不处理了
# 看下支付时间有没有16年以前的,支付时间在16年之后的这里就不处理了
df[df.payTime < startTime]

9、我们再把orderId重复的记录删掉

# 回过头来我们把orderId重复的记录删掉
df.orderId.unique().size

案例分析: 电商交易数据分析_第12张图片

  • 使用duplicated()找到重复记录并删除
# 删除orderId重复数据
df.drop(index=df[df.orderId.duplicated()].index, inplace=True)
  • 检查下是否删除成功
# 查看下
df.orderId.unique().size

10、把productId为0的也删除掉

# 把productId为0的也删除掉
df.drop(df[df.productId==0].index, inplace=True)
  • 检查下productId为0是否删除成功
# 查看下
df[df.productId==0]

在这里插入图片描述
至此,数据清洗完毕,开始分析了

三、分析与可视化

1、一般都是先看下数据的总体情况,比如:总订单数,总下单用户,总销售额,有流水的商品数

# 看下数据的总体情况
# 总订单数,总下单用户,总销售额,有流水的商品数
print(df.orderId.count())
print(df.userId.unique().size)
print(df.payMoney.sum()/100)
print(df.productId.unique().size)

分析数据可以从两方面开始考虑,一个是维度,一个是指标,维度可以看做x轴,指标可以看成是y轴,同一个维度可以分析多个指标,同一个维度也可以做降维升维。

2、按照商品的productId,先看下商品销量的前十和后十个

# 先看下商品销量的前十和后十个
productId_orderCount = df.groupby('productId').count()['orderId'].sort_values(ascending=False)
# 商品销量的前十个
productId_orderCount_head_10 = productId_orderCount.head(10)
fig = plt.figure(figsize = (20, 15),dpi=80)
f1 = fig.add_subplot(2, 2, 1)
f1.set_xlabel("商品ID", fontproperties="SimHei", size = 22)
f1.set_ylabel("销量(件)", fontproperties="SimHei", size = 22)
f1.set_title("2016年不同商品销量前10名", fontproperties="SimHei", size = 25)
f1.set_xticks(range(0, 10))
f1.set_xticklabels(productId_orderCount_head_10.index, size = 20)
f1.set_yticklabels(range(0, 351, 50), size = 20)
rects = f1.bar(range(0, len(productId_orderCount_head_10.index)), productId_orderCount_head_10.values, width = 0.5, color = "g")
for rect in rects:
    height = rect.get_height()
    f1.text(rect.get_x(), height+2, str(height), size = 15)
plt.grid(ls = "--", alpha = 0.5)

案例分析: 电商交易数据分析_第13张图片

# 商品销量的后十个
productId_orderCount_tail_10 = productId_orderCount.tail(10)
fig = plt.figure(figsize = (20, 15),dpi=80)
f1 = fig.add_subplot(2, 2, 1)
f1.set_xlabel("商品ID", fontproperties="SimHei", size = 22)
f1.set_ylabel("销量(件)", fontproperties="SimHei", size = 22)
f1.set_title("2016年不同商品销量后10名", fontproperties="SimHei", size = 25)
f1.set_xticks(range(0, 10))
f1.set_xticklabels(productId_orderCount_tail_10.index, size = 20)
f1.set_yticklabels(range(0, 31, 5), size = 20)
rects = f1.bar(range(0, len(productId_orderCount_tail_10.index)), productId_orderCount_tail_10.values, width = 0.5, color = "g")
for rect in rects:
    height = rect.get_height()
    f1.text(rect.get_x(), height+0.1, str(height), size = 15)
plt.grid(ls = "--", alpha = 0.5)

案例分析: 电商交易数据分析_第14张图片
3、使用sum聚合函数汇总统计下payMoney销售额前十和倒数前十的商品

# 看下销售额前十和倒数前十的商品
productId_turnover = df.groupby('productId').sum()['payMoney'].sort_values(ascending=False)
## 销售额前十
productId_turnover_head_10 = productId_turnover.head(10)
productId_turnover_head_max = round(productId_turnover_head_10.max())
# print(productId_turnover_head_10.index)
# print(productId_turnover_head_10.values)
fig = plt.figure(figsize = (20, 15))
f1 = fig.add_subplot(2, 2, 1)
f1.set_xlabel("商品ID", fontproperties="SimHei", size = 18)
f1.set_ylabel("销售额(元)", fontproperties="SimHei", size = 18)
f1.set_title("2016年不同商品销售额前10名", fontproperties="SimHei", size = 18)
f1.set_xticks(range(0, 10))
f1.set_xticklabels(productId_turnover_head_10.index, size = 18)
f1.set_yticklabels(range(0, productId_turnover_head_max, 50000), size = 18)
rects = f1.bar(range(0, len(productId_turnover_head_10.index)), productId_turnover_head_10.values, width = 0.5, color = "g")
for rect in rects:
    height = rect.get_height()
    f1.text(rect.get_x(), height+2, str(height), size = 15, rotation=15)
plt.grid(ls = "--", alpha = 0.5)

案例分析: 电商交易数据分析_第15张图片

## 商品销售额后10名
productId_turnover_tail_10 = productId_turnover.tail(10)
productId_turnover_tail_max = round(productId_turnover_tail_10.max())
fig = plt.figure(figsize = (20, 15))
f1 = fig.add_subplot(2, 2, 1)
f1.set_xlabel("商品ID", fontproperties="SimHei", size = 18)
f1.set_ylabel("销售额(元)", fontproperties="SimHei", size = 18)
f1.set_title("2016年不同商品销售额后10名", fontproperties="SimHei", size = 18)
f1.set_xticks(range(0, 10))
f1.set_xticklabels(productId_turnover_head_10.index, size = 18)
f1.set_yticklabels(range(0, productId_turnover_tail_max, 5000), size = 18)
rects = f1.bar(range(0, len(productId_turnover_tail_10.index)), productId_turnover_tail_10.values, width = 0.5, color = "g")
for rect in rects:
    height = rect.get_height()
    f1.text(rect.get_x(), height+2, str(height), size = 15, rotation=15)
plt.grid(ls = "--", alpha = 0.5)

案例分析: 电商交易数据分析_第16张图片
4、看下销量和销售额最后100个的交集,如果销量和销售额都不达标,这些商品需要看看是不是要优化或者下架

# 看下销量和销售额最后100个的交集,如果销量和销售额都不达标,这些商品需要看看是不是要优化或者下架
problem_productIds = productId_turnover.tail(100).index.intersection(productId_orderCount.tail(100).index)
problem_productIds

案例分析: 电商交易数据分析_第17张图片
5、城市的分析可以和商品维度类似

  • 看下城市的商品销量
# 城市的分析可以和商品维度类似
# 城市的商品销量
cityId_orderCount = df.groupby('cityId').count()['orderId'].sort_values(ascending=False)
cityId_orderCount
  • 看下城市的商品销售额
# 城市的商品销售额
cityId_payMoney = df.groupby('cityId').count()['payMoney'].sort_values(ascending=False)
cityId_payMoney

6、对于价格price,可以看下所有商品价格的分布,这样可以知道什么价格的商品卖的最好

  • 按照100的区间取分桶,价格是分,这里为了好看把他转成元
# 按照100的区间取分桶,价格是分,这里为了好看把他转成元
bins = np.arange(0, 25000, 100)
pd.cut(df.price, bins).value_counts()

案例分析: 电商交易数据分析_第18张图片
直方图

  • 觉得尺寸小的话可以先设置figsize,觉得后面的值没有必要展示,可以不用25000,改成10000
# 觉得尺寸小的话可以先设置figsize,觉得后面的值没有必要展示,可以不用25000,改成10000
plt.figure(figsize=(10, 8))
plt.hist(df['price'], bins)
plt.show()

案例分析: 电商交易数据分析_第19张图片

  • 很多价格区间没有商品,如果有竞争对手的数据,可以看看是否需要补商品填充对应的价格区间
# 很多价格区间没有商品,如果有竞争对手的数据,可以看看是否需要补商品填充对应的价格区间
price_cut_count = pd.cut(df.price, bins).value_counts()
zero_cut_result = (price_cut_count == 0)
zero_cut_result[zero_cut_result.values].index
  • 自定义一个数组分区间,使用pd.cut() 方法按1000分桶再看下
# 按1000分桶再看下
bins = np.arange(0, 5001, 1000)
price_cut = pd.cut(df.price, bins).value_counts()
price_cut

案例分析: 电商交易数据分析_第20张图片
饼图

  • 看看1000分桶的时候5000以下的饼图
# 看看1000分桶的时候5000以下的饼图
plt.figure(figsize=(8,8), dpi=80)
m = plt.pie(x=price_cut.values, labels=price_cut.index, autopct='%d%%', shadow=True)
plt.show(m)

案例分析: 电商交易数据分析_第21张图片
7、channelId的分析类似于productId,可以找出成交量最多的渠道,交易额最多的渠道等;渠道有时候是需要花钱买流量的,所以还需要根据渠道盈利情况和渠道成本进行综合比较。

  • 同时也可以渠道和商品等多个维度综合分析,看看不同的渠道卖的最好的商品是否相同

1> 按一天中下单时间分布情况分析

# 按下单时间分布情况分析
df['orderHour'] = df.createTime.dt.hour
df['orderHour'] 

案例分析: 电商交易数据分析_第22张图片
折线图

  • 一天中下单时间情况分布
order_hour_count = df['orderHour'].value_counts().sort_index()
# print(order_hour_count)
plt.figure(figsize = (12, 8))
_xticks = list(order_hour_count.index)
_xticks.append(24)
_x = [i-0.5 for i in range(0, 25)]
plt.xticks(_x, _xticks, size = 15)
plt.yticks(range(0, 14001, 2000), [i for i in range(0, 14001, 2000)], size = 15)
plt.xlabel("时间段", size = 18, fontproperties="SimHei")
plt.ylabel("订单数(件)", size = 18, fontproperties="SimHei")
plt.title("2016年在每日不同时间段的总订单数", size = 20, fontproperties="SimHei")
colors = ["#1C86EE"] * 24
colors[13] = "r"
colors[20] = "r"
rects = plt.bar(range(0, 24), order_hour_count.values, width = 1, edgecolor = "#B8B8B8", color = colors)
for rect in rects:
    height = rect.get_height()
    plt.text(rect.get_x(), height+80, str(height), size = 10)
plt.grid(ls = "--", alpha = 0.4)
plt.show()

案例分析: 电商交易数据分析_第23张图片

  • 按小时的下单分布,可以按时间做推广
    中午12,13,14点下单比较多,应该是午休的时候;
    然后是晚上20点左右,晚上20点左右几乎是所有互联网产品的一个高峰,下单高峰要注意网站的稳定性、可用性

2> 按一周下单时间分布情况分析

# 
df['orderWeek'] = df.createTime.dt.dayofweek
df['orderWeek']

案例分析: 电商交易数据分析_第24张图片

  • 一周中下单时间情况分布
# 不同星期的订单数
order_week_groupby = df.groupby('orderWeek').count()['orderId']
order_week_groupby.index = [i for i in range(1, 8)]
# ---- 绘图 ----
plt.figure(figsize = (8, 8))
_xticks = ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日", ]
plt.xticks(order_week_groupby.index, _xticks, size = 15, fontproperties="SimHei")
plt.yticks(size = 15)
plt.xlabel("时间", size = 18, fontproperties="SimHei")
plt.ylabel("订单数", size = 18, fontproperties="SimHei")
plt.title("2016年在每周不同时间的总订单数", size = 20, fontproperties="SimHei")
rects = plt.bar(order_week_groupby.index, order_week_groupby.values, width = 0.4)
for rect in rects:
    height = rect.get_height()
    plt.text(rect.get_x()-0.1, height+200, str(height), size = 15)
plt.grid(ls = "--", alpha = 0.4)
plt.show()

案例分析: 电商交易数据分析_第25张图片

  • 按照星期来看,周末两天的下单数居多

3> 下单后多久支付

# 下单后多久支付
def get_seconds(x):
    return x.total_seconds()
df['payDelta'] = (df['payTime'] - df['createTime']).apply(get_seconds)

bins = [0, 50, 100, 1000, 50000, 100000]
pd.cut(df['payDelta'], bins).value_counts()

案例分析: 电商交易数据分析_第26张图片

  • 饼图看下,有重合的话可以改下bins
# 饼图展示
pd.cut(df.payDelta, bins).value_counts().plot(kind='pie', autopct='%d%%', shadow=True, figsize=(10,10))
plt.show()

案例分析: 电商交易数据分析_第27张图片

  • 绝大部分都在十几分钟之内支付,说明用户基本很少犹豫,购买的目的性很强

4> 月成交额

  • 把创建订单的时间设置为索引
# 先把创建订单的时间设置为索引
df.set_index('createTime', inplace=True)
df.head()

案例分析: 电商交易数据分析_第28张图片

  • 每个月的总成交额的变化趋势
turnover = df.resample('M').sum()['payMoney']
turnover.plot()
plt.show()

案例分析: 电商交易数据分析_第29张图片

  • 每个月的总成交订单数的变化趋势
order_count = df.resample('M').count()['orderId']
order_count.plot()
plt.show()

案例分析: 电商交易数据分析_第30张图片
总结:
本案例主要对电商交易数据进行了一些常见的分析,包括了商品ID、商品价格、设备类型、下单时间等多个维度。因为不是多年的数据,因此无法做同比分析,而且数据不是企业内部的全部数据,所以原数据并没有出现像加购转化漏斗、网站流量等电商数据分析中常见的指标。不过,从仅有的数据来看,分析的结果基本符合我们的生活习惯,例如手机购物占多数、午休和晚饭后的休闲时间达到购物高峰期等。

你可能感兴趣的:(案例分析)