欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

python数据分析实战之电商交易分析

程序员文章站 2024-03-07 18:03:51
...

1、明确需求和目的

  • 通过以往的电商交易历史数据,分析商品销售的总体情况以及不同维度下的销售情况。

2、数据收集

  • 数据集为某电商平台2016年一整年的交易数据, 数据包含104557条数据,10个字段。
  • 除此之外,还有一个设备的转换说明文档。
    python数据分析实战之电商交易分析
    python数据分析实战之电商交易分析

3、数据预处理

3.1 数据整合
3.1.1 加载相关库和数据集
  • 使用的库主要有:pandas、numpy、matplotlib
  • 使用的数据集:某电商2016年交易情况的数据集文件和设备信息文件
# 加载数据分析需要使用的库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# 加载交易信息数据集
df = pd.read_csv('order_info_2016.csv', index_col='id')   
df.head()

python数据分析实战之电商交易分析

# 加载设备信息
device_type = pd.read_csv('device_type.txt')
device_type
------------------------
	id	deviceType
0	1	PC
1	2	Android
2	3	iPhone
3	4	Wap
4	5	other

数据整合,将两个文件的信息整合在一起:

df2 = pd.DataFrame()
df2["deviceType"] = device_type["id"]
df2["deviceName"] = device_type["deviceType"]
# 整合数据集信息和设备信息
df = pd.merge(df,df2,how='left')
3.1.2 数据概览

首先看一下数据集大小(行列信息):

df.shape
---------------------  # 相比原始数据,多了一列设备名称
(104557, 11)

看一下数据概况:

# df.info()
df.describe()

python数据分析实战之电商交易分析

3.2 数据清洗
3.2.1 缺失值处理

首先看一下缺失值情况:

df.isnull().sum(axis=0)    # 查看缺失值
----------------------------------------
orderId        0
userId         0
productId      0
cityId         0
price          0
payMoney       0
channelId      8
deviceType     0
createTime     0
payTime        0
deviceName    87
dtype: int64

发现 deviceName 有87个缺失值,而 deviceType 没有缺失值,看一下 deviceType 的取值分布:

df["deviceType"].value_counts()
----------------------------------
2    52448
3    42948
1     7054
4     2017
6       87
5        3
Name: deviceType, dtype: int64

发现这一列有类别为6的值,数量刚好为87,而设备信息文件并没有6这个类别,怀疑是信息填错了,将其重新归类为5,同时将 deviceName 的缺失值用"other"进行填充:

df['deviceType'].replace({6: 5}, inplace = True)
df.fillna({"deviceName": "other"}, inplace=True)

还有一列有8个缺失值,数据占比较少,我们直接将其删除:

df.dropna(inplace=True)
df.isnull().sum(axis=0)  
------------------------
orderId       0
userId        0
productId     0
cityId        0
price         0
payMoney      0
channelId     0
deviceType    0
createTime    0
payTime       0
deviceName    0
dtype: int64

删除缺失值之后,再来看一下数据集的大小:

df.shape
--------------------------
(104549, 11)
3.2.2 异常值处理

可以通过数据概况初步探索异常值:

df.describe()

python数据分析实战之电商交易分析

根据上面的结果可以看出 productId 最小值是0,payMoney 有负值,这明显是不合理的,我们需要对其进行处理。

首先看看 productId 值为0的数量,数量较少的话直接删除:

df.productId[(df.productId == 0)].size
-------------------------------------------------
177

# 177条记录,数量不多,直接删掉
df.drop(index=df[df.productId==0].index, inplace=True)

对于 payMoney 存在负值的记录,直接将其删除:

df.productId[(df.payMoney < 0)].size
----------------------------------------
6

# 只有6条记录,直接删除
df.drop(index=df[df.payMoney < 0].index, inplace=True)

再看一下这两列值的情况:

df[["productId", "payMoney"]].describe()
------------------------------------------
			productId	payMoney
count	104366.000000	1.043660e+05
mean	505.417626	8.690449e+04
std	287.629531	9.075357e+04
min	1.000000	0.000000e+00
25%	255.000000	3.360000e+04
50%	508.000000	5.500000e+04
75%	759.000000	1.040000e+05
max	1000.000000	2.294200e+06
3.2.3 多余记录的删除

因为是要分析2016年的数据,所以需要去除非2016年的数据,以及付款时间小于创建时间的数据:

import datetime

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

startTime = datetime.datetime(2016, 1, 1)
endTime = datetime.datetime(2016, 12, 31, 23, 59, 59)

df.drop(index=df[df.createTime < startTime].index, inplace=True)
df.drop(index=df[df.createTime > endTime].index, inplace=True)

# payTime早于createTime的也需要删掉
df.drop(index=df[df.createTime > df.payTime].index, inplace=True)
3.2.4 重复值的处理

首先看一下重复的行:

print(df.duplicated().sum())    # 查看重复值的数量
---------------------------------------
0

没有重复的行,但可能存在重复的订单号,按理说订单号是唯一的,我们来检查一下:

print(df.orderId.unique().size)
print(df.orderId.size)
--------------------------------
104339
104366

订单号存在重复值,我们对重复的记录进行删除:

df.drop(index=df[df.orderId.duplicated()].index, inplace=True)

其余字段有重复值是正常的,不需要进行处理。

4、数据分析

4.1 总体情况分析

先来看一下2016年一年的总体情况:

# 总订单数,总下单用户,总销售额,有销售的商品数
print(df.orderId.count())
print(df.userId.unique().size)
print(df.payMoney.sum()/100)        # 原单位是“分”,需要转换成“元”
print(df.productId.unique().size)
--------------------------------------
104329
102447
90666399.7
1000

再看看一下各个月的情况:

# 增加一个月份列,方便按照月份来进行统计
df['month'] = df["payTime"].dt.month

month = df["month"].unique()
order_count = df.groupby(by='month').count()["orderId"]
plt.bar(month, order_count)                 
plt.show()

python数据分析实战之电商交易分析

从上图可以看出,各个月的订单数并不均衡,最高峰集中在5-8月份,9-12月份订单数明显下降。针对这一现象可以着重考虑如何提高9-12月份份销量。

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

(1)商品分析

看一下销量前十名的商品:

productId_count = df.groupby('productId').count()['orderId'].sort_values(ascending=False)
print(productId_count.head(10))
-------------------------------------
productId
895    354
762    350
103    334
587    303
385    302
60     301
38     301
403    297
345    292
823    288
Name: orderId, dtype: int64

销量后十名的商品:

print(productId_count.tail(10))
productId
948     29
856     28
621     27
272     26
563     24
347     21
597     19
468     18
986     16
1000    13
Name: orderId, dtype: int64

可以看出,前十名和后十名的商品销量相差很大。

再看一下销售额前十名的商品:

# 原单位是“分”,需要转换成“元”
df['payMoney'] = df['payMoney'] / 100
productId_amount = df.groupby('productId').sum()['payMoney'].sort_values(ascending=False)
print(productId_amount.head(10))
-------------------------------------------
productId
385    427522.1
61     361572.0
103    344641.2
405    339525.0
720    322405.1
345    320162.2
698    318458.6
182    296600.0
383    280790.0
396    269556.0
Name: payMoney, dtype: float64

销售额后十名的商品:

print(productId_amount.tail(10))
------------------------------------
productId
310     22879.0
847     22869.0
454     22535.0
817     22509.0
597     21847.0
408     18111.0
986     14784.0
964     14238.0
1000    12169.0
347     12070.0
Name: payMoney, dtype: float64

根据以上的结果,对销售额/销量排名前十名的商品可以采取增加库存,增加推广成本等措施来进一步提升销量。而对于销售额/销量排名后十名的商品,则需要进行调研分析,确定商品销售额低下的原因,采取一定措施进行商品销量的提升,也可以考虑适当减少这些商品的库存,以减少损失。

看下销量和销售额最后100个商品的交集,如果销量和销售额都不达标,这些商品需要看看是不是要优化或者下架:

problem_productIds = productId_amount.tail(100).index.intersection(productId_count.tail(100).index)
print(len(problem_productIds))
print(problem_productIds.tolist())
----------------------------------------
58
[14, 807, 599, 676, 7, 469, 577, 551, 318, 220, 528, 303, 314, 359, 629, 582, 985, 218, 578, 227, 277, 145, 855, 586, 958, 91, 856, 948, 859, 874, 806, 272, 392, 27, 460, 436, 468, 579, 868, 137, 16, 590, 247, 569, 242, 104, 621, 478, 310, 847, 454, 817, 597, 408, 986, 964, 1000, 347]

一共有58个商品,可能需要进一步分析优化或者下架。

(2)城市分析

城市分析和商品分析类似,可以看一下销量和销售额都很高的城市,作为重点发展城市。

看一下销量前10的城市:

cityId_Count = df.groupby('cityId').count()['orderId'].sort_values(ascending=False)
print(cityId_Count.head(10))
-------------------------------------------
cityId
110001    5490
130001    4100
60011     3639
40001     3291
220002    3051
230001    2951
240001    2753
120001    2435
220005    2168
70001     2075
Name: orderId, dtype: int64

销售额前10的城市:

cityId_amount = df.groupby('cityId').sum()['payMoney'].sort_values(ascending=False)
print(cityId_amount.head(10))
-------------------------------
cityId
110001    6127732.8
220002    4406761.8
130001    3961264.7
220005    3374686.7
60011     2787478.1
40001     2531856.7
120001    2418538.8
70001     2192634.7
230001    2176484.0
220001    1983682.4
Name: payMoney, dtype: float64

销量和销售额都排名前5的城市:

good_cityId = cityId_amount.head(5).index.intersection(cityId_Count.head(5).index)
print(len(good_cityId))
print(good_cityId.tolist())
------------------------------------
4
[110001, 220002, 130001, 60011]

一共有4个城市销量和销售额表现优秀, 因此,我们可以针对这些城市开展更多的优惠活动或者线下活动,进一步提升销量。

(3)价格分析

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

# 原单位是“分”,需要转换成“元”
df['price'] = df['price'] / 100

# 先按照100的区间取分桶
bins = np.arange(0, 7500, 100)
print(pd.cut(df.price, bins).value_counts())
-----------------------------------------------
(400, 500]      14791
(300, 400]      10737
(200, 300]       9966
(500, 600]       9189
(600, 700]       8777
(100, 200]       7123
(700, 800]       7111
....
(6400, 6500]        2
(5500, 5600]        1
(7300, 7400]        0
Name: price, Length: 74, dtype: int64


plt.figure(figsize=(16, 16))
plt.hist(df['price'], bins)

python数据分析实战之电商交易分析
从上面可以看出,价格在400-500之间的商品卖的最好,大部分商品价格在0-1000之间,所以可以考虑进一步增加这些价格区间的商品。

(4)设备类型分析

下单设备排名:

df.groupby('deviceName').count()['orderId'].sort_values(ascending=False)
-------------------------------------------------------------
deviceName
Android    52340
iPhone     42852
PC          7033
Wap         2014
other         90
Name: orderId, dtype: int64

从上面可以看出,安卓和苹果客户端下单数最多,和大多数人使用手机网购相符合。如果想要进一步推广,应该将重点放在安卓客户端,其次是苹果客户端。

(5)下单时间分析

  • 按小时分析
# 按小时的下单量分布,可以按时间做推广
df['orderHour'] = df.createTime.dt.hour
df.groupby('orderHour').count()['orderId'].plot()

python数据分析实战之电商交易分析

从上图可以看出, 中午12-14点下单比较多,应该是午休的时候,然后是晚上20点左右,晚上20点左右几乎是所有互联网产品的一个高峰,下单高峰要注意网站的稳定性、可用性。下单高峰时间段也可以考虑进行推广,效果会更佳。

  • 按星期分析
df['orderWeek'] = df.createTime.dt.dayofweek + 1
df.groupby('orderWeek').count()['orderId'].plot()

python数据分析实战之电商交易分析

从上面可以看出,上班时间订单量不断上升,在周六达到顶峰,休息时间人们有更强的购买欲望,这也是比较符合现实的。

(5)支付时间分析

可以看一下客户在下单之后多久时间会进行支付:

def get_seconds(x):
    return x.total_seconds()
df['payDelta'] = (df['payTime'] - df['createTime']).apply(get_seconds)

bins = [0, 50, 100, 1000, 10000, 100000]
pd.cut(df.payDelta, bins).value_counts()
---------------------------------------
(0, 50]            79229
(100, 1000]        12899
(50, 100]          10674
(1000, 10000]        968
(10000, 100000]      231
Name: payDelta, dtype: int64

从上面可以看出,大部分人下单50秒以内就会进行支付,说明用户基本很少犹豫,购买的目的性很强。

用饼图看一下比例:

pd.cut(df.payDelta, bins).value_counts().plot(kind='pie', autopct='%d%%', shadow=True, figsize=(10, 4))

python数据分析实战之电商交易分析

5、总结

  • 通过对电商历史交易数据的清洗和分析,给出一些可以提升销量的建议,当然这只是简单的分析,需要更好的提升销量还需要更加深入和专业的分析才行。
相关标签: python数据分析