文章目录

  • 1、明确需求和目的
  • 2、数据收集
  • 3、数据预处理
  • 3.1 数据整合
  • 3.1.1 加载相关库和数据集
  • 3.1.2 数据概览
  • 3.2 数据清洗
  • 3.2.1 缺失值处理
  • 3.2.2 异常值处理
  • 3.2.3 多余记录的删除
  • 3.2.4 重复值的处理
  • 4、数据分析
  • 4.1 总体情况分析
  • 4.2 各维度分析
  • 5、总结

1、明确需求和目的

  • 通过以往的电商交易历史数据,分析商品销售的总体情况以及不同维度下的销售情况。
  • 根据分析结果提出有利于提升商品销量的建议。

2、数据收集

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

    python 电商 python做电商_python 电商_02

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 电商 python做电商_数据_03

# 加载设备信息
    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 电商 python做电商_缺失值_04

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 电商 python做电商_缺失值_05

根据上面的结果可以看出 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

没有重复的记录,不需要进行处理。

4、数据分析

4.1 总体情况分析

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

# 总订单数,总下单用户,总销售额,有销售的商品数
    print(df.orderId.count())
    print(df.userId.unique().size)
    print(df.payMoney.sum()/100)        # 原单位是“分”,需要转换成“元”
    print(df.productId.unique().size)
    --------------------------------------
    104356
    102474
    906931.2370000001
    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 电商 python做电商_python 电商_06

从上图可以看出,各个月的订单数并不均衡,存在着淡旺季之分。最高峰集中在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 电商 python做电商_python 电商_07

从上面可以看出,价格在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 电商 python做电商_ci_08

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

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

python 电商 python做电商_ci_09

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

(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 电商 python做电商_ci_10

5、总结

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