电商平台零售数据分析
1电商平台零售数据分析
环境为Anaconda3,Python3.8,用JupyterNotebook写的
数据文件在百度网盘
链接:https://pan.baidu.com/s/1DwWF4Vpduj8SqRUUezt4ew
提取码:2222
import plotly as py
py.offline.init_notebook_mode()
pyplot = py.offline.iplot
import plotly.graph_objs as go
from plotly.graph_objs import Scatter
from scipy import stats
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import os
os.chdir(r'E:\2020年Python数据分析师特训营全套84节视频完结版(就业向零基础友好)\2020年Python数据分析师特训营全套84节视频完结版')
df = pd.read_excel('超市数据.xlsx', dtype= {'Row ID':str})
df
#缺失率
df.apply(lambda x:sum(x.isnull())/len(x),axis=0)
#拷贝原文件为df1,防止数据丢失
df1 = df.copy()
df1
#去掉有缺失值的数据
df1.dropna(how='any')
# #去掉指定的两列
# df1.drop(['Unnamed: 24','Unnamed: 25'],axis=1,inplace=True)
#将Shipping Cost这一列中的缺失值替换为U
df['Shipping Cost'] = df['Shipping Cost'].fillna('U')
#先导入re模块,可以使用split一次加入多个切割条件
import re
#取出Ship Date这一列的每行字符串中以/分隔开的第一、二、三个元素
df1['ship_day'] = [re.split('\/|\-',x)[0] for x in df1['Ship Date']]
df1['ship_month'] = [re.split('\/|\-',x)[1] for x in df1['Ship Date']]
df1['ship_year'] = [re.split('\/|\-',x)[2] for x in df1['Ship Date']]
#将Order Date转换为datetime格式
df1['Order Date'] = pd.to_datetime(df1['Order Date'],errors='coerce')
df1['Order Date'] = df1['Order Date'].dt.date
#去重
df1 = df1.drop_duplicates()
#查看数据类型
df1.info()
#异常值处理之前先探索数据
df1.describe()
#将Sales Quantity Profit转换为float64
df1['Sales'] = pd.to_numeric(df1['Sales'], errors='coerce')
df1['Quantity'] = pd.to_numeric(df1['Quantity'], errors='coerce')
df1['Profit'] = pd.to_numeric(df1['Profit'], errors='coerce')
#计算Sales*Quantity保存为新的一列Price
df1['Price'] = df1.apply(lambda x:x['Sales']*x['Quantity'],axis=1)
df1.info()
df1
#异常值处理
df3 = df1.loc[df1['Quantity']<=0]
#计算异常值占比
df3.shape[0]/df1.shape[0]
#对异常值中的数量分类计数
df3['Quantity'].groupby(df3['Quantity']).count()
#df3中不同的年对应的不同的月份的退货金额
tt=pd.pivot_table(df3,index=['ship_year'],columns=['ship_month'],values=['Price'],aggfunc={'Price':np.sum},margins=False)
tt
#计算Profit>0的数量Quantity并按照State分组求和,按照降序排列,显示前十行,保存为quantity_first_10
quantity_first_10=df1[df1['Profit']>0].groupby(by='State').sum()['Quantity'].sort_values(ascending=False).head(10)
#画图
trace_basic=[go.Bar(x=quantity_first_10.index.tolist(),y=quantity_first_10.values.tolist(),marker=dict(color='orange'),opacity=0.50)]
layout=go.Layout(title='购买数量前十的国家',xaxis=dict(title='国家'))
figure_basic=go.Figure(data=trace_basic,layout=layout)
pyplot(figure_basic)
#交易额前十
price_first_10=df1[df1['Profit']>0].groupby(by='State').sum()['Price'].sort_values(ascending=False).head(10)
trace_basic1=[go.Bar(x=price_first_10.index.tolist(),y=price_first_10.values.tolist(),marker=dict(color='orange'),opacity=0.50)]
layout1=go.Layout(title='交易额前十的国家',xaxis=dict(title='国家'))
figure_basic1=go.Figure(data=trace_basic1,layout=layout1)
pyplot(figure_basic1)
#将Order Date转换为datetime格式
df1['Order Date'] = pd.to_datetime(df['Order Date'],errors='coerce')
#提取Order Date中的月份
df1['Month'] = df1['Order Date'].dt.month
#十二个月份盈利
profit_12=df1[df1['Profit']>0].groupby(by='Month').sum()['Profit'].sort_values(ascending=False)
trace_basic2=[go.Bar(x=profit_12.index.tolist(),y=profit_12.values.tolist(),marker=dict(color='orange'),opacity=0.50)]
layout2=go.Layout(title='十二个月份盈利条形图',xaxis=dict(title='月份'))
figure_basic2=go.Figure(data=trace_basic2,layout=layout2)
pyplot(figure_basic2)
#seaborn画图
sns.set(style='darkgrid',context='notebook',font_scale=1.2)
profit_12=df1[df1['Profit']>0].groupby(by='Month').sum()['Profit'].sort_values(ascending=False).plot(kind='bar')
#把x轴月份数字正过来
plt.xticks(rotation=360)
#客单价,就是每个客户的消费金额
#客单价 = 总消费金额 / 订单总量
#总消费金额
sum_price = df1[df1['Quantity']>0]['Price'].sum()
#计算客户ID数量
count_ID = df1[df1['Quantity']>0]['Customer ID'].count()
#客单价
avgprice = sum_price/count_ID
print(avgprice)
#客户ID去重计数
count_ID1=df1[df1['Quantity']>0]['Customer ID'].drop_duplicates().count()
print(count_ID1)
#按照 Customer ID聚合时,对Row ID去重计算下单次数,对Quantity和Price求和
customer=df1[df1['Quantity']>0].groupby('Customer ID').agg({'Row ID':'nunique','Quantity':np.sum,'Price':np.sum})
print(customer)
customer.describe()
#df2是取出df1中既满足['Quantity']>0又满足['Sales']>0的数据
df2 = df1[(df1['Quantity']>0) & (df1['Sales']>0)]
#RFM
# R_value是用户最近一次交易距今的时间
#按照Customer ID分类选出Order Date的最大值
R_value = df2.groupby('Customer ID')['Order Date'].max()
# Order Date中的最近时间-每位用户最近一次交易时间
R_value = (df2['Order Date'].max() - R_value).dt.days
# F_value是用户在限定的时间内所购买的次数
#按照Customer ID分类对Order ID去重计数
F_value = df2.groupby('Customer ID')['Order ID'].nunique()
# M_value是用户的交易金额
#按照Customer ID分类对Price求和
M_value = df2.groupby('Customer ID')['Price'].sum()
#描述分析R_value
R_value.describe()
#画出F_value满足F_value<200的分布柱状图
plt.hist(F_value[F_value<200],bins=30)
plt.show()
#设置分段标准
R_bins = [0,30,60,90,180,720]
F_bins = [1,2,5,10,20,500]
M_bins = [0,500,2000,5000,10000,200000]
#对用户最近一次交易距今的时间分段
R_score = pd.cut(R_value,R_bins,labels = [5,4,3,2,1],right=False)
R_score
#对用户在限定的时间内所购买的次数分段
F_score = pd.cut(F_value,F_bins,labels = [1,2,3,4,5],right=False)
#对用户的交易金额分段
M_score = pd.cut(M_value,M_bins,labels = [1,2,3,4,5],right=False)
#将R、F、M组合起来
RFM = pd.concat([R_score,F_score,M_score],axis=1)
#重命名各个变量
RFM.rename(columns={'Order Date':'R_score','Order ID':'F_score','Price':'M_score'},inplace=True)
#将RFM中的数据转换为float
for i in ['R_score','F_score','M_score']:
RFM[i] = RFM[i].astype(float)
#看平均值
RFM.describe()
#进行用户价值评测:大于平均值为高价值用户,否则为低价值用户
RFM['R'] = np.where(RFM['R_score'] > 3.594560,'高','低')
RFM['F'] = np.where(RFM['F_score'] > 3.857862,'高','低')
RFM['M'] = np.where(RFM['M_score'] > 4.243703,'高','低')
#将R、F、M三个评测等级以字符串形式连接保存为value一列
RFM['value'] = RFM['R'].str[:] + RFM['F'].str[:] + RFM['M'].str[:]
#去除value一列字符串头尾的空格
RFM['value'] = RFM['value'].str.strip()
#定义用户等级分类函数
def trans_value(x):
if x == '高高高':
return '重要价值客户'
elif x == '低高高':
return '重要保持客户'
elif x == '低低高':
return '重要挽留客户'
elif x == '高高低':
return '一般价值客户'
elif x == '高低低':
return '一般发展客户'
elif x == '低高低':
return '一般保持客户'
elif x == '高低高':
return '重要发展客户'
else:
return '一般挽留客户'
#对value一列使用用户等级分类函数
RFM['用户等级'] = RFM['value'].apply(trans_value)
#分类计数
RFM['用户等级'].value_counts()
#画条形图
trace_basic=[go.Bar(x=RFM['用户等级'].value_counts().index,y=RFM['用户等级'].value_counts().values,marker=dict(color='orange'),opacity=0.50)]
layout=go.Layout(title='用户等级情况',xaxis=dict(title='用户重要度'))
figure_basic=go.Figure(data=trace_basic,layout=layout,)
pyplot(figure_basic)
#画饼图
trace_basic1 = [go.Pie(labels = RFM['用户等级'].value_counts().index,values = RFM['用户等级'].value_counts().values,hole=0.2,textfont = dict(size=12,color='white'))]
layout1 = go.Layout(title = '用户等级比例')
figure_basic1 = go.Figure(data = trace_basic1,layout = layout1,)
pyplot(figure_basic1)
附图(大家可以自己敲一遍进行对照)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210325195651407.png?x-oss-
process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2N5cTEzNjQwMw,size_16,color_FFFFFF,t_70#pic_center)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210325195651414.png?x-oss-
process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2N5cTEzNjQwMw,size_16,color_FFFFFF,t_70#pic_center)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210325195651413.png?x-oss-
process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2N5cTEzNjQwMw,size_16,color_FFFFFF,t_70#pic_center)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210325195651410.png?x-oss-
process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2N5cTEzNjQwMw,size_16,color_FFFFFF,t_70#pic_center)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210325195651395.png?x-oss-
process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2N5cTEzNjQwMw==,size_16,color_FFFFFF,t_70#pic_center)
Python小白,数据分析与机器学习方向,每周六更