实战项目:物流行业数据分析

1、数据来源:某企业销售的6中商品所对应的送货及用户反馈数据

解决问题:

  1. 配送服务是否存在问题
  2. 是否存在有潜力的销售区域
  3. 商品是否存在质量问题

结论

  1. 货品4-西北,货品2-马来西亚,这两条线路存在较大问题,急需提升时效

  2. 货品2在华东地区还有较大的市场空间,适合加大投入;同时货品2在西北配送时效长,用户拒收率高,从成本角度考虑,应该减少投入

  3. 货品1、2、4质量存在问题,建议扩大抽检范围,增大质检力度

2、分析过程如下

一、数据清洗

  1. 重复值、缺失值、格式调整
  2. 异常值处理(比如:销售金额存在等于0的,属于异常)

二、数据规整
比如:增加一项辅助列:月份

三、数据分析并可视化

import os
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'SimHei'  ##显示中文字符

一、数据清洗

  1. 重复值、缺失值、格式调整
data = pd.read_csv('./Data/wuliu_data1/data_wuliu.csv', encoding='gbk')#encoding='utf-8'获取失败
data.info()   
---  ------  --------------  -----  
 0   订单号     1159 non-null   object 
 1   订单行     1161 non-null   int64  
 2   销售时间    1161 non-null   object 
 3   交货时间    1161 non-null   object 
 4   货品交货状况  1159 non-null   object 
 5   货品      1161 non-null   object 
 6   货品用户反馈  1161 non-null   object 
 7   销售区域    1161 non-null   object 
 8   数量      1157 non-null   float64
 9   销售金额    1161 non-null   object 

通过info()可以看出,包含10列数据,名字、数据量、格式等,可以得出:

  1. 订单号、货品交货情况、数量:存在缺失值,但是缺失量不大,可以删除
  2. 订单行,对分析无关紧要,没有实质意义,可以考虑删除
  3. 销售金额格式有问题(万元|元,逗号问题),数据类型需要转换为int|float
#删除重复记录,遇到重复保留第一行,删除后代替源数据
data.drop_duplicates(keep='first',inplace=True)
#删除缺失值(有na的整行数据,axis=0,how='any'默认)
data.dropna(axis=0,how='any',inplace=True)
#删除‘订单行’这一列:第二次运行删除操作会报错
data.drop(columns=['订单行'],inplace=True,axis=1)
#更新索引:drop=True:把原来的索引index列删除,重置index,原来的索引因为删除了行数据变乱
data.reset_index(drop=True,inplace=True)
data
订单号 销售时间 交货时间 货品交货状况 货品 货品用户反馈 销售区域 数量 销售金额
0 P096311 2016-7-30 2016-9-30 晚交货 货品3 质量合格 华北 2.0 1052,75元
1 P096826 2016-8-30 2016-10-30 按时交货 货品3 质量合格 华北 10.0 11,50万元
2 P097435 2016-7-30 2016-9-30 按时交货 货品1 返修 华南 2.0 6858,77元
3 P097446 2016-11-26 2017-1-26 晚交货 货品3 质量合格 华北 15.0 129,58元
4 P097446 2016-11-26 2017-1-26 晚交货 货品3 拒货 华北 15.0 32,39元
... ... ... ... ... ... ... ... ... ...
1141 P299901 2016-12-15 2017-3-15 按时交货 货品6 质量合格 马来西亚 2.0 200,41元
1142 P302956 2016-12-22 2017-3-22 按时交货 货品2 拒货 华东 20.0 79,44元
1143 P303801 2016-12-15 2017-3-15 按时交货 货品2 质量合格 华东 1.0 194,08元
1144 P307276 2016-12-22 2017-3-22 按时交货 货品6 质量合格 马来西亚 1.0 32,18元
1145 P314165 2016-12-20 2017-3-20 按时交货 货品2 质量合格 华东 1.0 1720,92元

1146 rows × 9 columns

#取出‘销售金额’列,对每个数据进行清洗,自定义map函数处理万元|元
#如果python已知函数不能满足我们的需求,就使用自定义函数:map、apply
#编写自定义过滤函数:1.删除逗号,2.转成float:如果是万元则删除万元再*10000;否则,删除元
def data_deal(number):
    if number.find('万元') != -1:#找到带有万元的,取出数字,去掉逗号,转成float,*10000
        #number[:number.find('万元')]去掉万元
        #number[:,number.find('万元')].replace(',','')将逗号替换为空
        number_new = float(number[:number.find('万元')].replace(',',''))*10000
        pass
    else: #找到带有元的,删除元,删除逗号,转成float
        if number.find('元') != -1:
            number_new = float(number.replace('元','').replace(',',''))
        pass
    return number_new

data['销售金额'] = data['销售金额'].map(data_deal)
data
订单号 销售时间 交货时间 货品交货状况 货品 货品用户反馈 销售区域 数量 销售金额
0 P096311 2016-7-30 2016-9-30 晚交货 货品3 质量合格 华北 2.0 105275.0
1 P096826 2016-8-30 2016-10-30 按时交货 货品3 质量合格 华北 10.0 11500000.0
2 P097435 2016-7-30 2016-9-30 按时交货 货品1 返修 华南 2.0 685877.0
3 P097446 2016-11-26 2017-1-26 晚交货 货品3 质量合格 华北 15.0 12958.0
4 P097446 2016-11-26 2017-1-26 晚交货 货品3 拒货 华北 15.0 3239.0
... ... ... ... ... ... ... ... ... ...
1141 P299901 2016-12-15 2017-3-15 按时交货 货品6 质量合格 马来西亚 2.0 20041.0
1142 P302956 2016-12-22 2017-3-22 按时交货 货品2 拒货 华东 20.0 7944.0
1143 P303801 2016-12-15 2017-3-15 按时交货 货品2 质量合格 华东 1.0 19408.0
1144 P307276 2016-12-22 2017-3-22 按时交货 货品6 质量合格 马来西亚 1.0 3218.0
1145 P314165 2016-12-20 2017-3-20 按时交货 货品2 质量合格 华东 1.0 172092.0

1146 rows × 9 columns

  1. 异常值处理
data.describe()
数量 销售金额
count 1146.000000 1.146000e+03
mean 76.069372 1.223488e+05
std 589.416486 1.114599e+06
min 1.000000 0.000000e+00
25% 1.000000 2.941500e+03
50% 1.000000 9.476500e+03
75% 4.000000 3.576775e+04
max 11500.000000 3.270000e+07
  • 销售金额最小值为0,有异常值
#1.销售金额==0,采用删除方法,因为数据量很小
data = data[data['销售金额']!=0]
data.describe()
#2.销售金额和数量存在严重的右偏现象,在电商领域2/8法则:20%的人贡献了80%的效率,少数人贡献了大多数的订单
#  很正常,无需处理
数量 销售金额
count 1145.000000 1.145000e+03
mean 76.134934 1.224557e+05
std 589.669861 1.115081e+06
min 1.000000 5.100000e+01
25% 1.000000 2.946000e+03
50% 1.000000 9.486000e+03
75% 4.000000 3.577300e+04
max 11500.000000 3.270000e+07

二、数据规整

  • 增加一项辅助列:月份

    • 配送服务是否存在问题——每个月配送服务的满意度
    • 是否存在尚有潜力的销售区域——根据月份绘制本月销售量的图,看月份和销售量的关系
  • 在数据中,从销售时间里提取月份,两种方法:

    • 字符串截取:.substr(data[‘销售时间’,6,2])
    • 将该列转化为datetime格式,直接month提取月份。
data['销售时间'] = pd.to_datetime(data['销售时间'])
data['月份'] = data['销售时间'].apply(lambda x: x.month)
data
订单号 销售时间 交货时间 货品交货状况 货品 货品用户反馈 销售区域 数量 销售金额 月份
0 P096311 2016-07-30 2016-9-30 晚交货 货品3 质量合格 华北 2.0 105275.0 7
1 P096826 2016-08-30 2016-10-30 按时交货 货品3 质量合格 华北 10.0 11500000.0 8
2 P097435 2016-07-30 2016-9-30 按时交货 货品1 返修 华南 2.0 685877.0 7
3 P097446 2016-11-26 2017-1-26 晚交货 货品3 质量合格 华北 15.0 12958.0 11
4 P097446 2016-11-26 2017-1-26 晚交货 货品3 拒货 华北 15.0 3239.0 11
... ... ... ... ... ... ... ... ... ... ...
1141 P299901 2016-12-15 2017-3-15 按时交货 货品6 质量合格 马来西亚 2.0 20041.0 12
1142 P302956 2016-12-22 2017-3-22 按时交货 货品2 拒货 华东 20.0 7944.0 12
1143 P303801 2016-12-15 2017-3-15 按时交货 货品2 质量合格 华东 1.0 19408.0 12
1144 P307276 2016-12-22 2017-3-22 按时交货 货品6 质量合格 马来西亚 1.0 3218.0 12
1145 P314165 2016-12-20 2017-3-20 按时交货 货品2 质量合格 华东 1.0 172092.0 12

1145 rows × 10 columns

三、数据分析并可视化

1. 配送服务是否存在问题——按时交货率

  • 月份维度
  • 销售区域维度
  • 货品维度
  • 货品和销售区域维度

a.月份维度分析按时交货率

#有的‘货品交货状况’内容,开头含有空格,需要删除首位空格 **.strip()**
data['货品交货状况'] = data['货品交货状况'].str.strip()
data1 = data.groupby(['月份','货品交货状况']).size().unstack()#按月份和货币交货状况分类,.size()计算数量
#.unstack() 可以使输出表格更直观,方便后面计算
data1['按时交货率'] = data1['按时交货']/ (data1['按时交货']+data1['晚交货'])
data1
货品交货状况 按时交货 晚交货 按时交货率
月份
7 189 13 0.935644
8 218 35 0.861660
9 122 9 0.931298
10 238 31 0.884758
11 101 25 0.801587
12 146 18 0.890244
  • 分析结果:从按时交货率来看,第四季度低于第三季度,猜测可能是气候原因造成的

b.销售区域维度分析按时交货率

data2 = data.groupby(['销售区域','货品交货状况']).size().unstack()
data2['按时交货率'] = data2['按时交货']/ (data2['按时交货']+data2['晚交货'])
print(data1.sort_values(by='按时交货率', ascending=False))
货品交货状况  按时交货  晚交货     按时交货率
月份                         
7        189   13  0.935644
9        122    9  0.931298
12       146   18  0.890244
10       238   31  0.884758
8        218   35  0.861660
11       101   25  0.801587
  • 分析结果:西北存在突出的延时交货问题,急需解决

c.货品维度分析按时交货率

data3 = data.groupby(['货品', '货品交货状况']).size().unstack()
data3['按时交货率'] = data3['按时交货'] / (data3['按时交货']+data3['晚交货'])
print(data3.sort_values(by='按时交货率', ascending=False))
货品交货状况  按时交货  晚交货     按时交货率
货品                         
货品5      183    4  0.978610
货品6      309    7  0.977848
货品1       27    2  0.931034
货品3      212   26  0.890756
货品2      269   48  0.848580
货品4       14   44  0.241379
  • 分析结果:货品4晚交货非常严重,其余货品相对正常

d.货品和销售区域结合分析按时交货率

data4 = data.groupby(['货品','销售区域','货品交货状况']).size().unstack()
data4['按时交货率'] = data4['按时交货'] / (data4['按时交货']+data4['晚交货'])
print(data4.sort_values(by='按时交货率',ascending=False))
货品交货状况     按时交货   晚交货     按时交货率
货品  销售区域                       
货品5 泰国    183.0   4.0  0.978610
货品6 马来西亚  309.0   7.0  0.977848
货品1 华北     14.0   1.0  0.933333
    华南     10.0   1.0  0.909091
货品3 华北    212.0  26.0  0.890756
货品2 华东    268.0  39.0  0.872964
货品4 西北     14.0  44.0  0.241379
货品2 马来西亚    1.0   9.0  0.100000
货品1 西北      3.0   NaN       NaN
  • 分析结果:

销售区域:最差在西北地区,货品有1和4,主要是货品4送货过晚导致的;

货品角度:最差的是货品2,主要送往华东和马来西亚,主要是马来西亚的送货较晚导致。

2. 是否存在尚有潜力的销售区域——货品的销售数量

  • 月份维度
  • 销售区域维度
  • 月份和销售区域维度

a.月份维度分析货品销售数量

  • 每个月,每个商品的销售情况
data1 = data.groupby(['月份','货品'])['数量'].sum().unstack()
data1
data1.plot(kind='line')

实战项目:物流行业数据分析_第1张图片

  • 结果分析:货品2在10月和12月份,销量猛增。原因猜测有二:1。公司加大营销力度 2.开发了新的市场(在研究区域维度确定)

b. 销售区域维度分析货品销售数量

data2 = data.groupby(['货品', '销售区域'])['数量'].sum().unstack()
data2
销售区域 华东 华北 华南 泰国 西北 马来西亚
货品
货品1 NaN 2827.0 579.0 NaN 11.0 NaN
货品2 53811.0 NaN NaN NaN NaN 1510.0
货品3 NaN 9073.5 NaN NaN NaN NaN
货品4 NaN NaN NaN NaN 5229.0 NaN
货品5 NaN NaN NaN 5733.0 NaN NaN
货品6 NaN NaN NaN NaN NaN 8401.0
  • 结果分析:从销售区域看,每种货品销售区域为1~3个,货品1有3个销售区域,货品2有两个销售区域,其余货品均有1个销售区域

c. 月份和销售区域

data3 = data.groupby(['月份','销售区域','货品'])['数量'].sum().unstack() 
data3['货品2'].unstack() #只能查看最后分组的指标
销售区域 华东 华北 华南 泰国 西北 马来西亚
月份
7 489.0 NaN NaN NaN NaN 2.0
8 1640.0 NaN NaN NaN NaN 1503.0
9 3019.0 NaN NaN NaN NaN 1.0
10 28420.0 NaN NaN NaN NaN NaN
11 2041.0 NaN NaN NaN NaN 1.0
12 18202.0 NaN NaN NaN NaN 3.0
  • 结果分析:
    1.前面遇到的问题,货品2在10月和12月份销量激增,还是发生在原有销售区域(华东),没有扩展新的销路
    2.同样,分析出在7,8,9,11月份销量数量还有很大提升空间,需要适当加大营销力度。

3. 商品是否存在质量问题——货品用户反馈

  • 月份维度
  • 销售区域维度
  • 月份和销售区域维度

注:字符串字段记得在统计之前删除首位空格,.str.strip()

a. 从货品和销售地区维度进行分析

data['货品用户反馈'] = data['货品用户反馈'].str.strip()  #取出首位空格
data1 = data.groupby(['货品', '销售区域'])['货品用户反馈'].value_counts().unstack()
# 计算拒收率
data1['拒货率'] = data1['拒货'] / data1.sum(axis=1)#按行进行求和汇总
data1['返修率'] = data1['返修'] / data1.sum(axis=1)
data1['合格率'] = data1['质量合格'] / data1.sum(axis=1)
data1.sort_values(['合格率', '返修率', '拒货率'], ascending=False)#先按合格率排序,再按返修率,拒货率; 降序
货品用户反馈 拒货 质量合格 返修 拒货率 返修率 合格率
货品 销售区域
货品3 华北 31.0 188.0 19.0 0.130252 0.079788 0.789219
货品6 马来西亚 56.0 246.0 14.0 0.177215 0.044279 0.777936
货品5 泰国 14.0 144.0 29.0 0.074866 0.155018 0.769108
货品2 华东 72.0 184.0 51.0 0.234528 0.165997 0.598568
货品1 华南 5.0 4.0 2.0 0.454545 0.174603 0.343963
西北 NaN 1.0 2.0 NaN 0.666667 0.272727
华北 NaN 3.0 12.0 NaN 0.800000 0.189873
货品4 西北 NaN 9.0 49.0 NaN 0.844828 0.152945
货品2 马来西亚 6.0 1.0 3.0 0.600000 0.283019 0.091886
data1
货品用户反馈 拒货 质量合格 返修 拒货率 返修率 合格率
货品 销售区域
货品1 华北 NaN 3.0 12.0 NaN 0.800000 0.189873
华南 5.0 4.0 2.0 0.454545 0.174603 0.343963
西北 NaN 1.0 2.0 NaN 0.666667 0.272727
货品2 华东 72.0 184.0 51.0 0.234528 0.165997 0.598568
马来西亚 6.0 1.0 3.0 0.600000 0.283019 0.091886
货品3 华北 31.0 188.0 19.0 0.130252 0.079788 0.789219
货品4 西北 NaN 9.0 49.0 NaN 0.844828 0.152945
货品5 泰国 14.0 144.0 29.0 0.074866 0.155018 0.769108
货品6 马来西亚 56.0 246.0 14.0 0.177215 0.044279 0.777936

结果分析:

  • 货品3,6,5合格率均较高,返修率比较低,说明质量还可以

  • 货品1,2,4合格率较低,返修率较高,质量存在一定问题,需要改善

  • 货品2在马来西亚的拒货率较高,结合按时收货率来看,货品2在马来西亚的按时收货率也很低——可以猜测马来西亚人对货品的时效性要求较高,如果达不到,则往往考虑拒绝收货。

  • 那么是否要减小对马来西亚的投入呢?增大对华东地区的投入?

    • 考虑到货品2主要在华东地区销售量大,可以考虑增大在华东地区的投资,适当减小对马来西亚的投入

你可能感兴趣的:(数据分析项目,数据分析,python,数据挖掘)