基于Python的超市零售数据分析

本文使用Python对全球超市的零售数据进行深入分析,包括销售额、销量、利润、客单价、用户行为等方面,揭示销售季节性、商品销售表现、用户群体特征,并通过RFM模型进行客户价值评估,提出提升销量的策略建议。
摘要由CSDN通过智能技术生成

分析框架:
在这里插入图片描述

一、明确需求和目的

  • 对一家全球超市的四年(2012-2015)销售数据进行“人、货、场”分析,并给出提升销量的针对性建议。
  • 场:整体运营情况分析,包括销售额、销量、利润、客单价、市场布局等具体情况分析。
  • 货:商品结构、优势/畅销商品、劣势/待优化商品等情况分析。
  • 人:客户数量、新老客户、RFM模型、复购率、回购率等用户行为分析。

二、数据介绍

  • 数据来源于Kaggle平台,这是一份全球大型超市五年的零售数据集,数据信息详尽。
  • 数据集为"全球超市订单数据.xlsx",共51290条数据记录,每条记录共24个特征。

三、数据预处理

3.1 导入相关库并读取数据

import pandas as pd 
import numpy as np 
import matplotlib.pyplot as plt 
import seaborn as sns

plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置中文显示 
plt.rcParams['axes.unicode_minus'] = False # 设置坐标轴负数显示

pd.set_option('display.width', 300) # 设置字符显示宽度
pd.set_option('display.max_rows', None) # 设置显示最大行 
pd.set_option('display.max_columns', None) # 设置显示最大列
data = pd.read_excel('全球超市订单数据.xlsx')
data.sample(5)
行 ID 订单 ID 订购日期 装运日期 装运方式 客户 ID 客户名称 细分市场 邮政编码 城市 省市 国家 地区 市场 产品 ID 类别 子类别 产品名称 销售额 数量 折扣 利润 装运成本 订单优先级
21696 22861 IN-2013-BM117857-41593 2013-11-15 2013-11-17 二级 BM-117857 Bryan Mills 消费者 NaN Nowra 新南威尔士 澳大利亚 大洋洲 亚太地区 OFF-AR-3453 办公用品 艺术 BIC Highlighters, Fluorescent 54.513 3 0.1 1.773 10.82
5749 12597 ES-2015-IM1505545-42098 2015-04-04 2015-04-08 标准级 IM-1505545 Ionia McGrath 消费者 NaN Tourcoing 北部-加来海峡-庇卡底 法国 西欧 欧洲 OFF-ST-5702 办公用品 存储 Rogers Lockers, Single Width 380.970 2 0.1 143.910 58.64
20879 51267 MG-2015-DK289584-42210 2015-07-25 2015-07-28 一级 DK-289584 Dana Kaydos 消费者 NaN Ulan Bator 乌兰巴托 蒙古 东亚 亚太地区 FUR-FU-3027 家具 用具 Advantus Door Stop, Black 45.030 1 0.0 9.450 11.58
23683 30075 IN-2015-TN2104027-42136 2015-05-12 2015-05-15 一级 TN-2104027 Tanja Norvell 家庭办公室 NaN Shangqiu 河南省 中国 东亚 亚太地区 OFF-AR-3502 办公用品 艺术 Binney & Smith Sketch Pad, Water Color 99.000 2 0.0 13.860 9.15
46704 12192 ES-2014-AG10675120-41731 2014-04-02 2014-04-07 标准级 AG-10675120 Anna Gayman 消费者 NaN Barcelona 加泰罗尼亚 西班牙 南欧 欧洲 OFF-BI-3290 办公用品 装订机 Avery Hole Reinforcements, Durable 23.640 4 0.0 8.400 1.51 媒介
# 查看数据行列数
data.shape
>(51290, 24)
# 查看数据的分布概况 
data.describe()
行 ID 邮政编码 销售额 数量 折扣 利润 装运成本
count 51290.00000 9994.000000 51290.000000 51290.000000 51290.000000 51290.000000 51290.000000
mean 25645.50000 55190.379428 246.490581 3.476545 0.142908 28.610982 26.478567
std 14806.29199 32063.693350 487.565361 2.278766 0.212280 174.340972 57.251373
min 1.00000 1040.000000 0.444000 1.000000 0.000000 -6599.978000 1.002000
25% 12823.25000 23223.000000 30.758625 2.000000 0.000000 0.000000 2.610000
50% 25645.50000 56430.500000 85.053000 3.000000 0.000000 9.240000 7.790000
75% 38467.75000 90008.000000 251.053200 5.000000 0.200000 36.810000 24.450000
max 51290.00000 99301.000000 22638.480000 14.000000 0.850000 8399.976000 933.570000

3.2 对列名格式进行规范

根据上面展示的数据可以发现数据的列名不符合Python的命名规范,列名不应该包含空格,应去除或用下划线连接,这里采用去除空格对列名进行重命名。

data.rename(columns=lambda x:x.replace(' ',''),inplace=True)
data.columns
Index(['行ID', '订单ID', '订购日期', '装运日期', '装运方式', '客户ID', '客户名称', '细分市场', '邮政编码', '城市', '省市', '国家', '地区', '市场', '产品ID', '类别', '子类别', '产品名称', '销售额', '数量', '折扣', '利润', '装运成本', '订单优先级'], dtype='object')

3.3 数据类型处理

# 查看各列数据类型 
# data.info() 
data.dtypes
行ID               int64
订单ID             object
订购日期     datetime64[ns]
装运日期     datetime64[ns]
装运方式             object
客户ID             object
客户名称             object
细分市场             object
邮政编码            float64
城市               object
省市               object
国家               object
地区               object
市场               object
产品ID             object
类别               object
子类别              object
产品名称             object
销售额             float64
数量                int64
折扣              float64
利润              float64
装运成本            float64
订单优先级            object
dtype: object

可以看到各列数据类型与其字段数据值相符,因此不需要进行数据类型转换。

为了 方便分析每年和每月的销售情况,增加“Year”和“Month”列:

data['Year'] = data['订购日期'].dt.year
data['Month'] = data['订购日期'].values.astype('datetime64[M]')
data[['Year','Month']].head()
Year Month
0 2014 2014-11-01
1 2014 2014-02-01
2 2014 2014-10-01
3 2014 2014-01-01
4 2014 2014-11-01

3.4 缺失值处理

# 查看各字段的数据是否存在缺失 
data.isnull().any()
行ID      False
订单ID     False
订购日期     False
装运日期     False
装运方式     False
客户ID     False
客户名称     False
细分市场     False
邮政编码      True
城市       False
省市       False
国家       False
地区       False
市场       False
产品ID     False
类别       False
子类别      False
产品名称     False
销售额      False
数量       False
折扣       False
利润       False
装运成本     False
订单优先级    False
Year     False
Month    False
dtype: bool
# 发现只有邮政编码存在缺失值,统计查看一下存在多少缺失值(行数是51290)
data['邮政编码'].isnull().sum()
41296

发现邮政编码列几乎80%都是缺失值,显然该列已经对我们的分析没有太大作用,因此进行删除。

data.drop('邮政编码', axis=1, inplace=True) 

3.5 异常值处理

data.describe()
行ID 销售额 数量 折扣 利润 装运成本 Year
count 51290.00000 51290.000000 51290.000000 51290.000000 51290.000000 51290.000000 51290.000000
mean 25645.50000 246.490581 3.476545 0.142908 28.610982 26.478567 2013.777208
std 14806.29199 487.565361 2.278766 0.212280 174.340972 57.251373 1.098931
min 1.00000 0.444000 1.000000 0.000000 -6599.978000 1.002000 2012.000000
25% 12823.25000 30.758625 2.000000 0.000000 0.000000 2.610000 2013.000000
50% 25645.50000 85.053000 3.000000 0.000000 9.240000 7.790000 2014.000000
75% 38467.75000 251.053200 5.000000 0.200000 36.810000 24.450000 2015.000000
max 51290.00000 22638.480000 14.000000 0.850000 8399.976000 933.570000 2015.000000

从上面展示的结果可以确定没有明显的异常值,因此不需要进行处理。

3.6 重复值处理

# 查看是否存在完全重复的行:
data.duplicated().sum()
0

0说明没有完全重复的记录,因此不需要进行处理

四、数据分析

4.1 整体销售情况分析

首先构造整体销售情况的数据子集:

  • 包含:订购日期、年份、月份、销售额、销量、利润
sales_data = data[['订购日期','Year','Month','销售额','数量','利润']]
sales_data.head()
订购日期 Year Month 销售额 数量 利润
0 2014-11-11 2014 2014-11-01 221.980 2 62.1544
1 2014-02-05 2014 2014-02-01 3709.395 9 -288.7650
2 2014-10-17 2014 2014-10-01 5175.171 9 919.9710
3 2014-01-28 2014 2014-01-01 2892.510 5 -96.5400
4 2014-11-05 2014 2014-11-01 2832.960 8 311.5200

按照年、月对销售数据子集进行分组求和统计:

sales_year_grouped = sales_data.groupby(by=['Month']).agg('sum')
sales_year_grouped.sample(5)
Year 销售额 数量 利润
Month
2014-10-01 2215400 293406.64288 3883 42433.22258
2012-01-01 871196 98898.48886 1463 8321.80096
2014-04-01 1580990 177821.31684 2688 19462.03844
2012-08-01 1740380 208063.28372 3020 26452.99742
2014-12-01 3226428 405454.37802 5694 50202.87112

对上面进行分组求和后的数据进行拆分,将每一年的数据分配一张独立的表:

year_2012 = sales_year_grouped['2012':'2012'].reset_index()
year_2013 = sales_year_grouped['2013':'2013'].reset_index() 
year_2014 = sales_year_grouped['2014':'2014'].reset_index() 
year_2015 = sales_year_grouped['2015':'2015'].reset_index()
year_2015
Month Year 销售额 数量 利润
0 2015-01-01 1849770 241268.55566 3122 28001.38626
1 2015-02-01 1523340 184837.35556 2482 19751.69996
2 2015-03-01 2152020 263100.77262 3722 37357.26052
3 2015-04-01 2117765 242771.86130 3594 23782.30120
4 2015-05-01 2587260 288401.04614 4300 33953.55774
5 2015-06-01 3522220 401814.06310 6009 43778.60280
6 2015-07-01 2190305 258705.68048 3637 28035.87258
7 2015-08-01 3375125 456619.94236 5824 53542.89496
8 2015-09-01 4066270 481157.24370 6837 67979.45110
9 2015-10-01 3276390 422766.62916 5876 58209.83476
10 2015-11-01 4326205 555279.02700 7706 62856.58790
11 2015-12-01 4338295 503143.69348 7513 46916.52068
4.1.1 销售额分析(按月)
# 构建销售额表 
sales = pd.concat([year_2012['销售额'],year_2013['销售额'],
                   year_2014['销售额'],year_2015['销售额']],axis=1)
# 重构行列名 
sales.index = [str(i+1)+'月' for i in range(12)]
sales.columns = ['sales_2012','sales_2013','sales_2014','sales_2015']

# 绘制热力图,颜色越深表示销售额越高
plt.figure(figsize=(8,6))
sns.heatmap(sales,cmap='RdPu',annot=True,fmt='.2f',linewidths=0.5)
# plt.yticks(rotation=90)
plt.show()

在这里插入图片描述

从上图可以看出,基本每年的下半年的销售额都比上半年要高,而且随着年份的增长,销售额也在逐年增加,可以说明该超市的发展还是比较好的

肉眼可以看见每一年的销售额都比前一年要好,那么现在来实际计算一下每年的销售总额和具体的增长率:

# 每年的总销售额 
sales_sum = sales.sum()
# 计算销售额增长率 
rise_rates = [0]
for i in range(len(sales_sum)-1):
    rise_rate = round((sales_sum[i+1]-sales_sum[i])/sales_sum[i]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值