文章目录
数据集来源
数据集来自UCI加州大学欧文分校机器学习库:
https://archive.ics.uci.edu/ml/datasets/online+retail
该数据集为英国在线零售商在2010年12月1日至2011年12月9日间发生的所有网络交易信息。该公司主要销售礼品,拥有许多批发商客户。
字段解释
InvoiceNo:发票编号。为每笔订单唯一分配的6位整数。若以字母’C’开头,则表示该订单被取消。
StockCode:产品代码。为每个产品唯一分配的编码。
Description:产品描述。
Quantity:数量。每笔订单中各产品分别的数量。
InvoiceDate:发票日期和时间。每笔订单发生的日期和时间。
UnitPrice:单价。单位产品价格,单位为英镑。
CustomerID:客户编号。为每个客户唯一分配的5位整数。
Country:国家。客户所在国家/地区的名称。
项目需求
1.订单维度:订单金额与订单内商品件数是否存在相关性?
2.客户维度:客户消费金额与消费件数是否存在相关性?
3.商品维度:热销产品排名,哪种价位的商品带来了实际上最多的销售额?
4.时间维度:销量走势?可能受到了什么影响?
5.区位维度:客户主要来自哪几个国家?哪个国家是境外主要市场?哪个国家的客户平均消费能力最强?
6.客户行为:客户的生命周期、留存情况、购买周期如何?
数据清洗
#####数据导入######
import numpy as np
import pandas as pd
dt = pd.read-excel(r'D:\working data\Online Retail.xlsx.xlsx,dtype=str)
#####去重######
dt.shape[0]#去重前简单查看数据的行
dt.drop_duplicates(inplace=True)
dt.shape[0]#去重后再次查看
dt.rest_index(drop=True,inplace=True)#重新构建索引
######查看空值######
dt.isnull().sum()
#发现CustomerID和Description有空值,且CustomerID的空值较多,做一个简单填充
dt['CustomerID'].fillna('123',inplace=True)
######对时间做一致化处理#########
dt['InvoiceTime']=pd.to_datetime(dt['InvoiceDate'],errors='coerce')
dt['Date'] = pd.to_datetime(dt['InvoiceTime'].dt.date, errors='coerce')
dt['Month'] = dt['InvoiceTime'].astype('datetime64[M]')
######对字符串类型做一致化处理#######
dt['Quantity'] = dt['Quantity'].astype('int32')#转换成整型
dt['UnitPrice'] = dt['UnitPrice'].astype('float')#转换成浮点型
dt['CustomerID'] = dt['CustomerID'].astype('int32')#转换成整型
########对数据进行一次统计性描述##########
dt.describe()
#发现Quantily有小于0的数值,UnitPrice也有等于0的值
dt[(dt['Quantity'] <= 0)|(dt['UnitPrice'] <= 0)]#查看两者小于零的所有数据
发现这些数据有一个特点,Quantity<=0的订单编号前面都有字母C,表明是退货了,UnitPrice=0可能是赠品
对这些数据做一个简单处理:
query_c = dt['InvoiceNo'].str.contains('C')#提取InvoiceNo列中含C字母的列
sales_cancel = dt.loc[query_c,:].copy()#将query_c所涉及的所有行提取出来赋值
sales_success = dt.loc[-query_c,:].copy()#将query_c无关的行提取出来赋值
######将单价为0的商品剥离出来###########
query_free = sales_success['UnitPrice'] == 0
sales_cancel = sales_success.loc[query_free,:].copy()
sales_success = sales_success.loc[-query_free,:]
对于UnitPrice<0,由于原始数据中也没有进行说明,且数据量少,此处就当作异常值处理,直接剥离
query_minus = sales_success['UnitPrice'] < 0
sales_success.loc[query_minus,:]
sales_success = sales_success.loc[-query_minus,:]
将处理完成的数据做一个保存,准备分析
sales_success.to_excel(r'D:\pycharm\working data\Online Retail_clean.xlsx')
数据分析
订单维度
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
#打开处理完的数据
dt =pd.read_excel(r'D:\working data\Online Retail_clean.xlsx')
#求一下每笔订单的总价
dt['SumPrice']= dt['UnitPrice']*dt['Quantity']
#根据每笔订单号分类,然后求一下每一笔下单的数量和与每一笔订单的总价
invoice_grouped = dt.groupby('InvoiceNo')[['Quantity','SumPrice']].sum()
#求得每笔订单的平均价格和连带率
invoice_grouped.describe()
平均价格和连带率:
在这里插入图片描述
从图中可以看出,数据集(2010年12月1日-2011年12月9日)内共有19960笔订单,每笔平均单价为533.17英镑,连带率为279件。订单交易金额和订单内商品件数,其均值都高于中位数;订单交易金额的均值甚至高于Q3分位数。说明订单总体差异大,存在部分购买力极强的客户。
订单交易额分布图
#####绘制交易金额分布图##########
plt.figure(figsize=(14,4))
plt.subplot(121)
invoice_grouped['SumPrice'].hist(bins = 100,figsize = (12,4),color = 'b')
plt.title('SumPrice Distribution of Orders')
plt.ylabel('Frequency')
plt.xlabel('SumPrice')
########部分订单交易金额过大,影响图表的可读性,筛去1000英镑及以上的订单#######
plt.subplot(122)
invoice