电商交易数据分析-Python
1.这是一份关于某电脑平台2016年的交易数据,通过分析这份数据,我们可以知道这一整年的销售情况。
数据解读:
id:ID
order_id:订单ID
user_id:用户ID
productId:产品ID
cityId:城市的ID
price:价格
payMoney:支付金额
channelId:渠道ID
deviceType:设备类型
createTime:创建时间
payTime:支付时间
2.分析目的:
2.1订单量前10的商品ID
2.2销售额前10的商品ID
2.3订单量前10的城市
2.4销售额前10的城市
2.5订单量前10的渠道
2.6销售额前10的渠道
2.7各个时间段的订单量
2.8各个时间段的销售额
2.9工作日的订单量
2.10工作日的销售额
2.11月的订单量
2.12月的销售额
2.13季度的订单量
2.14季度的销售额
2.15那个价格区间的购买人数比较多
2.16支付金额在那个价格区间比较多
2.17各个设备类型的订单量的占比
2.18各设备类型的销售情况(订单量+销售额)
3.数据清洗
3.1导入常用的包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'SimHei'
%matplotlib inline
# parse_dates将createTime、payTime设置成datetime格式,
# 方便后期的增加年月日,小时辅助列
df = pd.read_csv('order_info_2016.csv', engine='python',
parse_dates=['createTime', 'payTime'])
3.2使用shape和info()和describe()查看表情况:
1.channelId有缺失值。
2.productId有为0的产品。
3.payMoney有负值。
df.shape
输出:
df.info()
输出:
df.describe()
3.3清洗orderId这一列。我们都知道orderId在一个系统里是唯一值,先看下有没重复的值。
这里有104557-104530=27条orderId重复的数据。
进一步查看重复的数据:
df[df.orderId.isin(df[df.orderId.duplicated()].orderId)].sort_values(by="orderId")
输出:
重复的数据是不同的购买时间,数据只有27条,后期直接删除处理。
3.4userId列清洗
userId从上面的info()和describe()看下值在正常的范围。
对于订单数据集,一个用户可能有多个订单,重复值是合理的。
# 这里查询到不用的用户ID有102672
# 相当于1885个复购的用户
df.userId.unique().size
输出:
3.5productId列的清洗
productId的最小值是0,先看下值为0的记录数值
# 这里的productI为0的数据有177条,可能是由于商品下架将productId设置为0
# 这里将这177条当做异常数据,直接删除处理
df[df.productId==0].shape
后期直接删除处理。
3.6.cityId列清洗
从上面的info()和describe()看出值都在正常范围,不需要处理
# 有331个不同的城市
df.cityId.unique().size
输出:
3.7price列清洗
price没有空值,且都大于0,这里的单位是分,将它转换成元
# 这里的价格都是分的,转换成元
df['price'] = df['price'] / 100
df.sample()
输出:
3.8payMoney列的清洗
payMoney有负值,我们下单不可能有负值,所以这里对负值的记录要删除掉。
# 这里有支付金额小于0的异常数据,只有6条,直接删除处理
df[df.payMoney < 0]
输出:
删除:
df.drop(index=df[df.payMoney < 0].index, inplace=True)
重新看下数据有没删除:
df[df.payMoney < 0]
没有输出数据,证明异常数据已删除。
将payMoney转换成元。
df['payMoney'] = df['payMoney'] / 100
3.9channelId列的清洗
channelId根据info()的结果,有些null的数据,可能是端的bug问题,在下单的时候没有传channelId字段。
# 这里有8条challelId为null的数据,直接删除处理
df[df.channelId.isnull()]
输出:
删除处理:
df.drop(index=df[df.channelId.isnull()].index, inplace=True)
3.10deviceType这列的数据根据info()和describe()都没有问题,不用处理
3.11createTime和payTime列的清洗
createTime和payTime都没有null,不过我们要统计的是2016年的数据,所以把非2016年的删掉。
payTime类似,这里只按创建订单的时间算,就不处理了。
# 删除2016年之前的数据
import datetime
startTime = datetime.datetime(2016,1,1)
endTime = datetime.datetime(2016,12,31,23,59,59)
df[df.createTime < startTime]
df.drop(index=df[df.createTime < startTime].index, inplace=True)
输出:
payTime早于createTime的也需要删掉
df.drop(index=df[df.createTime>df.payTime].index, inplace=True)
处理16年之后的数据
# 删除2016之后的数据
# 这里没有,就不用处理了
df[df.createTime>endTime]
看下支付时间有没有在2016年以前的,支付时间在16年之后的这里就不处理了。
df[df.payTime<startTime]
3.12回头删除orderId重复的数据
df.drop(index=df[df.orderId.duplicated()].index, inplace=True)
3.13删除productId为0的数据
df.drop(index=df[df.productId==0].index, inplace=True)
至此,数据清洗完毕,可以进行分析。
4.可视化+分析
4.1订单量前10的商品ID
# 先按照商品的productID
# 先看下商品销量前10的商品
product_order_num = df.groupby('productId').count()['orderId'].reset_index().rename(columns={
'orderId': 'order_num'}).sort_values('order_num', ascending=False)
# 这里加个下划线,方便绘图
product_order_num['productId'] = product_order_num['productId'].apply(lambda x: "_" + str(x))
# 可视化
product_order_num_top_10 = product_order_num.head(10)
import seaborn as sns
plt.figure(figsize=(4,3), dpi=128)
sns.barplot(x='order_num', y='productId', data=product_order_num_top_10)
plt.xticks(rotation=70)
for a, b in enumerate(product_order_num_top_10.order_num):
plt.text(b, a, b, va='center', ha='center')
输出:
4.2销售额前10的商品ID
product_sale_num = df.groupby('productId').sum()[
'payMoney'].reset_index().sort_values(by='payMoney', ascending=False)
product_sale_num['productId'] = product_sale_num['productId'].apply(lambda x: "_" + str(x))
#可视化
product_sale_num_top_10 = product_sale_num.head(10)
plt.figure(figsize=(4,3), dpi=128)
sns.barplot(x='payMoney', y='productId', data=product_sale_num_top_10)
plt.xticks(rotation=70)
for a, b in enumerate(product_sale_num_top_10.payMoney):
plt.text(b, a, b, va='center', ha='center')
输出:
4.3订单量前10的城市
city_order_num = df.groupby('cityId').count()['orderId'].reset_index().rename(columns={
'orderId': 'order_num'
}).sort_values(by='order_num', ascending=False)
city_order_num['cityId'] = city_order_num['cityId'].apply(lambda x: "_" + str(x))
#可视化
city_order_num_top_10 = city_order_num.head(10)
plt.figure(figsize=(4,3), dpi=128)
sns.barplot(x='order_num', y='cityId', data=city_order_num_top_10)
plt.xticks(rotation=70)
for a, b in enumerate(city_order_num_top_10.order_num):
plt.text(b, a, b, va='center', ha='center')
输出:
4.4销售额前10的城市
city_sale_num = df.groupby('cityId').sum()['payMoney'].reset_index().sort_values(by='payMoney',
ascending=False)
city_sale_num['cityId'] = city_sale_num['cityId'].apply(lambda x: "_" + str(x))
#可视化
city_sale_num_top_10 = city_sale_num.head(10)
plt.figure(figsize=(4,3), dpi=128)
sns.barplot(x='payMoney', y='cityId', data=city_sale_num_top_10)
plt.xticks(rotation=70)
for a, b in enumerate(city_sale_num_top_10.payMoney):
plt.text(b, a, b, va='center', ha='center')
输出:
4.5订单量前10的渠道
channel_order_num = df.groupby('channelId').count()['orderId'].reset_index().rename(columns={
'orderId': 'order_num'}).sort_values(by='order_num',ascending=False)
#可视化
channel_order_num_top_10 = channel_order_num.head(10)
plt.figure(figsize=(4,3), dpi=128)
sns.barplot(x='order_num', y='channelId', data=channel_order_num_top_10)
plt.xticks(rotation=70)
for a, b in enumerate(channel_order_num_top_10.order_num):
plt.text(b, a, b, va='center', ha='center')
输出:
4.6销售额前10的渠道
channel_sale_num = df.groupby('channelId').sum()['payMoney'].reset_index().sort_values(by='payMoney',
ascending=False)
#可视化
channel_sale_num_top_10 = channel_sale_num.head(10)
plt.figure(figsize=(4,3), dpi=128)
sns.barplot(x='payMoney', y='channelId', data=channel_sale_num_top_10)
plt.xticks(rotation=70)
for a, b in enumerate(channel_sale_num_top_10.payMoney):
plt.text(b, a, round(b,0), va='center', ha='left')
输出:
4.7各个时间段的订单量
#增加hour辅助列
df['hour'] = df.createTime.dt.hour
df.sample(10)
输出:
hour_order_num = df.groupby('hour').count()['orderId'].reset_index().rename(columns={
'orderId': 'order_num'
})
#可视化
plt.figure(figsize=(4,3), dpi=128)
sns.barplot(x='hour', y='order_num', data=hour_order_num)
plt.xticks(rotation=70)
输出:
4.8各个时间段的销售额
hour_sale_num = df.groupby('hour').sum()['payMoney'].reset_index()
#可视化
plt.figure(figsize=(4,5), dpi=128)
sns.barplot(x='hour', y='payMoney', data=hour_sale_num)
plt.xticks(rotation=70)
输出:
4.9工作日的订单量
#增加星期几这个辅助列
df['dayofweek'] = df.createTime.dt.dayofweek
dayofweek_order_num = df.groupby('dayofweek').count()['orderId'].reset_index().rename(columns={
'orderId': 'order_num'
})
#将0-6数字转黄成星期几
def parse_int_to_week(x):
if x==0:
return "星期一"
elif x==1:
return "星期二"
elif x==2:
return "星期三"
elif x==3:
return "星期四"
elif x==4:
return "星期五"
elif x==5:
return "星期六"
elif x==6:
return "星期天"
dayofweek_order_num['dayofweek'] = dayofweek_order_num['dayofweek'].apply(parse_int_to_week)
#可视化
plt.figure(figsize=(4,3), dpi=128)
sns.barplot(x='order_num', y='dayofweek', data=dayofweek_order_num)
plt.xticks(rotation=70)
for a, b in enumerate(dayofweek_order_num.order_num):
plt.text(b, a, b, va='center', ha='left')
输出:
4.10工作日的销售额
dayofweek_sale_num = df.groupby('dayofweek').sum()['payMoney'].reset_index()
dayofweek_sale_num['dayofweek'] = dayofweek_sale_num['dayofweek'].apply(parse_int_to_week)
#可视化
plt.figure(figsize=(4,3), dpi=128)
sns.barplot(x='payMoney', y='dayofweek', data=dayofweek_sale_num)
plt.xticks(rotation=70)
for a, b in enumerate(dayofweek_sale_num.payMoney):
plt.text(b, a, round(b, 1), va='center', ha='left')
输出:
4.11月的订单量
#增加月这个辅助列
df['month'] = df.createTime.dt.month
month_order_num = df.groupby('month').count()['orderId'].reset_index().rename(columns={
'orderId': 'order_num'
})
month_order_num['month'] = month_order_num['month'].apply(lambda x: str(x) + "月")
#可视化
plt.figure(figsize=(4,3), dpi=128)
sns.barplot(x='month', y='order_num', data=month_order_num)
plt.xticks(rotation=70)
for a, b in enumerate(month_order_num.order_num):
plt.text(a, b, b, va='center', ha='left', rotation=90)
输出:
4.12月的销售额
month_sale_num = df.groupby('month').sum()['payMoney'].reset_index()
month_sale_num['month'] = month_sale_num['month'].apply(lambda x: str(x) + "月")
#可视化
plt.figure(figsize=(4,3), dpi=128)
sns.barplot(x='month', y='payMoney', data=month_sale_num)
plt.xticks(rotation=70)
for a, b in enumerate(month_sale_num.payMoney):
plt.text(a, b, round(b,0), va='center', ha='center', rotation=90)
输出:
4.13季度的订单量
#增加季度辅助列
def parse_month_to_quarter(x):
if x<=3:
return "Q1"
elif x<=6:
return "Q2"
elif x<=9:
return "Q3"
else:
return "Q4"
df['quarter'] = df['month'].apply(parse_month_to_quarter)
quarter_order_num = df.groupby('quarter').count()['orderId'].reset_index().rename(columns={
'orderId': 'order_num'
})
#可视化
plt.figure(figsize=(4,3), dpi=128)
sns.barplot(x='order_num', y='quarter', data=quarter_order_num)
plt.xticks(rotation=70)
for a, b in enumerate(quarter_order_num.order_num):
plt.text(b, a, round(b, 1), va='center', ha='left')
输出:
4.14季度的销售额
quarter_sale_num = df.groupby('quarter').sum()['payMoney'].reset_index()
#可视化
plt.figure(figsize=(4,3), dpi=128)
sns.barplot(x='payMoney', y='quarter', data=quarter_sale_num)
plt.xticks(rotation=70)
for a, b in enumerate(quarter_sale_num.payMoney):
plt.text(b, a, round(b, 1), va='center', ha='left')
输出:
4.15那个价格区间的购买人数比较多
price_bins_100 = np.arange(0, 5000, 100)
plt.figure(figsize=(8, 6), dpi=128)
plt.hist(df.price, price_bins_100)
输出:
4.16支付金额在那个价格区间比较多
plt.figure(figsize=(4, 3), dpi=128)
payMoney_bins_200 = np.arange(0, 5000, 200)
payMoney_cut = pd.cut(df.payMoney, payMoney_bins_200)
payMoney_cut.value_counts().plot(kind='bar')
输出:
4.17各个设备类型的订单量的占比
device_order_num = df.groupby('deviceType').count()[
'orderId'].reset_index().rename(columns={'orderId': 'order_num'})
plt.pie(device_order_num.order_num, labels=device_order_num.deviceType, autopct="%.1f")
plt.show()
输出:
4.18各设备类型的销售情况(订单量+销售额)
device_sale_num = df.groupby('deviceType').sum()['payMoney'].reset_index()
device_sale_num['deviceType'] = device_sale_num['deviceType'].apply(lambda x: str(x))
#可视化
plt.figure(figsize=(4, 3), dpi=128)
sns.barplot(x='deviceType', y='payMoney', data=device_sale_num)
plt.twinx()
sns.lineplot(x='deviceType', y='order_num', data=device_order_num, label='订单量')
plt.legend()
输出:
上一篇: php 表单提交错误后返回数据消失问题的解决方法,php表单
下一篇: Linux系统网卡设图文详解