物流行业数据分析学习记录

一、数据清洗

(1)重复值、缺失值、格式调整

调用模块,导入数据:

import os
import pandas as pd
import numpy as np
import matplotlib as plt
plt.rcParams['font.sans-serif']='SimHei'
data=pd.read_csv('data_wuliu.csv',encoding='gbk')
data.info()

运行结果:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1161 entries, 0 to 1160
Data columns (total 10 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 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 
dtypes: float64(1), int64(1), object(8)
memory usage: 90.8+ KB

可以看出,文件包括10列数据的名字,数据量,格式等,以1161个数据为基准,缺失的数据数量并不多,所以可以直接删除;订单号对分析没有实质性意义,删除;销售金额需要改成float;总结如下:

1.订单号,货品交货情况,数量:存在缺失值,但是量不大,可以删除

2.订单行,对分析无关紧要,可以考虑删除

3.销售金额格式不对(万元|元,逗号问题),数据类型需要转换成int|float

# 删除重复记录
data.drop_duplicates(keep='first',inplace=True)#如果手动设定为True(默认为False),那么原数组直接就被替换。而采用inplace=False之后原数组名对应的内存值并不改变
print(data.info())
# 删除带有na的整行数据
data.dropna(axis=0,how='any',inplace=True)
# 删除订单行
data.drop(columns=['订单行'],inplace=True,axis=1)
print(data.info())
# 这里运行会报错,因为第一次已经删除了订单行这一字段,需要重新加载数据后再次运行
#每次运行这一cell,都需要先运行前一部分的代码,否则报错
data.reset_index(drop=True,inplace=True)#前面删除了行后索引乱了,更新一下

运行结果:

<class 'pandas.core.frame.DataFrame'>
Index: 1152 entries, 0 to 1160
Data columns (total 10 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   订单号     1150 non-null   object 
 1   订单行     1152 non-null   int64  
 2   销售时间    1152 non-null   object 
 3   交货时间    1152 non-null   object 
 4   货品交货状况  1150 non-null   object 
 5   货品      1152 non-null   object 
 6   货品用户反馈  1152 non-null   object 
 7   销售区域    1152 non-null   object 
 8   数量      1150 non-null   float64
 9   销售金额    1152 non-null   object 
dtypes: float64(1), int64(1), object(8)
memory usage: 99.0+ KB
None
<class 'pandas.core.frame.DataFrame'>
Index: 1146 entries, 0 to 1160
Data columns (total 9 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   订单号     1146 non-null   object 
 1   销售时间    1146 non-null   object 
 2   交货时间    1146 non-null   object 
 3   货品交货状况  1146 non-null   object 
 4   货品      1146 non-null   object 
 5   货品用户反馈  1146 non-null   object 
 6   销售区域    1146 non-null   object 
 7   数量      1146 non-null   float64
 8   销售金额    1146 non-null   object 
dtypes: float64(1), object(8)
memory usage: 89.5+ KB
None

取出销售金额列,对每一个数据进行清洗;编写自定义行数:删除逗号,若单位为万元则乘以一万,否则消除单位元,转成float

def data_deal(number):
    if number.find('万元')!= -1:#找到带有万元的,取出数字,去掉逗号,转成float,*10000
        number_new = float(number[:number.find('万元')].replace(',',''))*10000
        pass
    else: #找到带有元的,删除元,删除逗号,转成float
        number_new = float(number.replace('元','').replace(',',''))
        pass
    return number_new
data['销售金额'] = data['销售金额'].map(data_deal)

运行结果:

订单号销售时间交货时间货品交货状况货品货品用户反馈销售区域数量销售金额
0P0963112016-7-302016-9-30晚交货货品3质量合格华北2.0105275.0
1P0968262016-8-302016-10-30按时交货货品3质量合格华北10.011500000.0
2P0974352016-7-302016-9-30按时交货货品1返修华南2.0685877.0
3P0974462016-11-262017-1-26晚交货货品3质量合格华北15.012958.0
4P0974462016-11-262017-1-26晚交货货品3拒货华北15.03239.0
..............................
1141P2999012016-12-152017-3-15按时交货货品6质量合格马来西亚2.020041.0
1142P3029562016-12-222017-3-22按时交货货品2拒货华东20.07944.0
1143P3038012016-12-152017-3-15按时交货货品2质量合格华东1.019408.0
1144P3072762016-12-222017-3-22按时交货货品6质量合格马来西亚1.03218.0
1145P3141652016-12-202017-3-20按时交货货品2质量合格华东1.0172092.0

1146 rows × 9 columns

(2)预处理-异常值处理和偏态分布

(比如:销售金额存在等于0的,数量和销售金额的标准差都在均值的8倍以上等)

data.describe()

运行结果:

数量销售金额
count1146.0000001.146000e+03
mean76.0693721.223488e+05
std589.4164861.114599e+06
min1.0000000.000000e+00
25%1.0000002.941500e+03
50%1.0000009.476500e+03
75%4.0000003.576775e+04
max11500.0000003.270000e+07

销量平均是76,中位数却是1,说明后1/2的数远远大于1,说明数据右偏;销售金额平均值与中位数差10的二次幂倍,也体现了数据右偏;但同时需考虑其他因素如行业特征。

# 销售金额==0,采用删除方法,因为数据量小
data=data[data['销售金额']!=0]
# data.describe()
# 销售金额与数量存在严重的右偏现象,符合电商行业的二八法则,无需处理

这里由涉及电商行业,因此较为符合实际;但若是其他行业则需要再行考虑。

二、数据规整

考虑到配送服务、销售潜力的分析需要以月份为单位,这里需要把数据转换成月份的。

data['销售时间']=pd.to_datetime(data['销售时间'])
data['月份']=data['销售时间'].apply(lambda x:x.month)
data

运行结果:

订单号销售时间交货时间货品交货状况货品货品用户反馈销售区域数量销售金额月份
0P0963112016-07-302016-9-30晚交货货品3质量合格华北2.0105275.07
1P0968262016-08-302016-10-30按时交货货品3质量合格华北10.011500000.08
2P0974352016-07-302016-9-30按时交货货品1返修华南2.0685877.07
3P0974462016-11-262017-1-26晚交货货品3质量合格华北15.012958.011
4P0974462016-11-262017-1-26晚交货货品3拒货华北15.03239.011
.................................
1141P2999012016-12-152017-3-15按时交货货品6质量合格马来西亚2.020041.012
1142P3029562016-12-222017-3-22按时交货货品2拒货华东20.07944.012
1143P3038012016-12-152017-3-15按时交货货品2质量合格华东1.019408.012
1144P3072762016-12-222017-3-22按时交货货品6质量合格马来西亚1.03218.012
1145P3141652016-12-202017-3-20按时交货货品2质量合格华东1.0172092.012

1145 rows × 10 columns

三、数据分析及可视化

1、配送服务是否存在问题

a.月份维度
data['货品交货状况']=data['货品交货状况'].str.strip()#去除首位空格
data1=data.groupby(['月份','货品交货状况']).size().unstack()#以月份和交货状况进行分组,统计出有多少条数据,unstack是不要堆叠
data1['按时交货率']=data1['按时交货']/(data1['按时交货']+data1['晚交货'])
data1

运行结果:

货品交货状况按时交货晚交货按时交货率
月份
7189130.935644
8218350.861660
912290.931298
10238310.884758
11101250.801587
12146180.890244

从按时交货率来看,第四季度低于第三季度,猜测是受季节影响。

b.销售区域维度
data1=data.groupby(['销售区域','货品交货状况']).size().unstack()
data1['按时交货率']=data1['按时交货']/(data1['按时交货']+data1['晚交货'])
print(data1.sort_values(by="按时交货率",ascending=False))

运行结果:

货品交货状况  按时交货  晚交货     按时交货率
销售区域                       
泰国       183    4  0.978610
马来西亚     310   16  0.950920
华南        10    1  0.909091
华北       226   27  0.893281
华东       268   39  0.872964
西北        17   44  0.278689

可以看出西北地区存在严重的延时交货问题,急需解决。

c.货品维度
data1=data.groupby(['货品','货品交货状况']).size().unstack()#以月份和交货状况进行分组,统计出有多少条数据,unstack是不要堆叠
data1['按时交货率']=data1['按时交货']/(data1['按时交货']+data1['晚交货'])
print(data1.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.货品与销售区域结合
data1=data.groupby(['货品','销售区域','货品交货状况']).size().unstack()
data1['按时交货率']=data1['按时交货']/(data1['按时交货']+data1['晚交货'])
print(data1.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.plot(kind='line')

运行结果:

 货品2在10月和12月销售猛增,原因猜测有二:公司加大营销力度或开发了新市场。

b.不同区域
data1=data.groupby(['销售区域','货品'])['数量'].sum().unstack()
print(data1)

运行结果:

货品       货品1      货品2     货品3     货品4     货品5     货品6
销售区域                                                 
华东       NaN  53811.0     NaN     NaN     NaN     NaN
华北    2827.0      NaN  9073.5     NaN     NaN     NaN
华南     579.0      NaN     NaN     NaN     NaN     NaN
泰国       NaN      NaN     NaN     NaN  5733.0     NaN
西北      11.0      NaN     NaN  5229.0     NaN     NaN
马来西亚     NaN   1510.0     NaN     NaN     NaN  8401.0

 从销售区域看,每种货品有1到3个销售区域,除货品1有3个销售区域,货品2有两个销售区域外,其余货品均有1个销售区域。

c.月份和区域
data1=data.groupby(['月份','销售区域','货品'])['数量'].sum().unstack()
data1['货品2']

运行结果:

月份  销售区域
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
11  华东       2041.0
    华北          NaN
    华南          NaN
    泰国          NaN
    西北          NaN
    马来西亚        1.0
12  华东      18202.0
    华北          NaN
    华南          NaN
    泰国          NaN
    西北          NaN
    马来西亚        3.0
Name: 货品2, dtype: float64

可以看出,货品2在10月、12月销量猛增,原因主要发生在原有的华东销售区域;同样,分析出在7、8、9、11月份销售数量的可提升空间还很大。

3.商品是否存在质量问题

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.0188.019.00.1302520.0797880.789219
货品6马来西亚56.0246.014.00.1772150.0442790.777936
货品5泰国14.0144.029.00.0748660.1550180.769108
货品2华东72.0184.051.00.2345280.1659970.598568
货品1华南5.04.02.00.4545450.1746030.343963
西北NaN1.02.0NaN0.6666670.272727
华北NaN3.012.0NaN0.8000000.189873
货品4西北NaN9.049.0NaN0.8448280.152945
货品2马来西亚6.01.03.00.6000000.2830190.091886

可以看出:

  • 货品3,6,5合格率较高,返修率比较低,质量不错;
  • 货品1,2,4合格率较低,返修率较高,质量需要改善;
  • 货品2在马来西亚的拒货率最高,同时按时交货率也非常低,猜测马来西亚人对送货时效性要求较高,若达不到则考虑拒货;
  • 考虑到货品2主要在华东地区销量较大,可以考虑增加在华东地区的投资,适当减小对马来西亚的投入。

三.结论

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

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

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


概览

数据来源:

某企业销售的6种商品所对应的送货及用户反馈数据

解决问题:

1、配送服务是否存在问题

2、是否存在尚有潜力的销售区域

3、商品是否存在质量问题

结论:

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

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

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

分析过程

    一、数据清洗

① 重复值、缺失值、格式调整

② 异常值处理(比如:销售金额存在等于0的,数量和销售金额的标准差都在均值的8倍以上等)

    二、数据规整

比如:增加一项辅助列:月份

    三、数据分析

经验:

标题包含1-6个级别,1级的标题字最大,6级的标题字最小,如果一行的开头使用“#”,并且后面空一格,就能被认为是标题,根据“#”的多少,代表不同的标题级别:

# 我是一级标题
## 我是二级标题
### 我是三级标题
#### 我是四级标题
##### 我是五级标题
###### 我是六级标题

来源于:代码神器jupyter的文字排版技巧(一) - 知乎 (zhihu.com)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值