餐厅订单表格数据资源如下百度网盘
链接:https://pan.baidu.com/s/18cgy6UFqg71gEyFa0l0ftg 提取码:ye9p
# 代码块在jupyter notebook可一路执行
import pandas as pd # pandas 包是处理表格数据的主战力
import numpy as np # numpy 包用于处理科学计算
import matplotlib.pyplot as plt # matplotlib.pyplot 用于画图
# 设置plt中字体为黑体,主要是为了方便中文显示
plt.rcParams['font.sans-serif'] = 'SimHei'
# 读取excel表格中名为meal_order_detail1的子表数据。下边同理
data1=pd.read_excel('meal_order_detail.xlsx',sheet_name='meal_order_detail1')
data2=pd.read_excel('meal_order_detail.xlsx',sheet_name='meal_order_detail2')
data3=pd.read_excel('meal_order_detail.xlsx',sheet_name='meal_order_detail3')
# concat方法:拼接列表中的pandas数据,axis代表方向,0是按行拼接
data=pd.concat([data1,data2,data3],axis=0)
data
# dropna方法:删除空值,axis代表方向【1代表按列删除】,inplace为True代表在原数据进行修改
data.dropna(axis=1,inplace=True)
# 查看表列基本信息,确认是否删除成功
# info方法:输出各列取值,类型,总数等情况
data.info()
# round方法:四舍五入,后一个参数为保留x个小数
# mean方法:numpy中的求平均值方法
mean_price=round(np.mean(data['amounts']),2)
# 同理,pandas中也有mean方法,不过数据较大时用numpy会比较快
# round(data['amounts'].mean(),2)
mean_price
# pandas 的 value_counts() 方法:统计相同元素的个数【默认降序】,返回的是Series
# 使用切片取前10个数据
dishes_count=data['dishes_name'].value_counts()[:10]
dishes_count
# pandas也有画图方法,其与 pyplot 画出来的是同一个图,每一列数据正好对应
# kind代表画图类型【bar是柱状图】,color是颜色,fontsize可以设置字体大小
dishes_count.plot(kind='bar',fontsize=16,color='green')
# 订单中出现的名字是唯一的,如果同样菜有多份会在 count 这一列进行计数
# 所以仅需统计各个 order_id 数量就可知道对应订单点了多少菜
cuisine_kind_top10 = data['order_id'].value_counts()[:10]
cuisine_kind_top10.plot(kind='bar')
plt.title('点菜种类最多的前10个订单')
plt.xlabel('订单ID')
plt.ylabel('点菜种类')
plt.show()
# 为 data 数据多添加一列,存储菜品的总消费金额【同样菜品有多份】
# 数量*单价就是总价
data['total_amounts'] = data['counts'] * data['amounts']
# 取出订单号,菜品数量,菜品总价并根据 order_id 进行分组形成 group
# counts 和 total_amounts 其他列数据分组压缩时候利用 sum() 进行求和
# order_id 会成为 group 的索引
group = data[['order_id', 'counts', 'total_amounts']
].groupby(by='order_id').sum()
# group 中对 counts 进行倒序排序,前十个就是我们的答案
counts_top10 = group.sort_values(by='counts', ascending=False)
# 索引 order_id 成为 x 轴
counts_top10['counts'][:10].plot(kind='bar')
plt.title('点菜数量最多的前10个订单')
plt.xlabel('订单ID')
plt.ylabel('点菜数量')
plt.show()
# 前面已经将每个订单的总消费金额都统计出并放在 group 中,此处仅进行排序即可
total_amounts_top10=group.sort_values(by='total_amounts',ascending=False)
total_amounts_top10['total_amounts'][:10].plot(kind='bar')
plt.xlabel('订单ID')
plt.ylabel('消费金额')
plt.title('消费金额最多的前10个订单')
plt.show()
# 为 group 增加一列,每个订单的总金额/菜品数就是当前订单的平均金额
group['avg_amounts']=group['total_amounts']/group['counts']
# 递减排序
avg_amounts_top10=group.sort_values(by='avg_amounts',ascending=False)
avg_amounts_top10['avg_amounts'][:10].plot(kind='bar')
plt.xlabel('订单ID')
plt.ylabel('平均消费单价')
plt.title('平均消费单价最多的前10个订单')
plt.show()
# 新列,用作计数器,初始整列为1
data['hourcount'] = 1
# 将 Excel 列中读取的文本时间转换成日期类型存储
data['place_order_time'] = pd.to_datetime(data['place_order_time'])
# 添加新列 hour,日期类型的 hour 属性对应的是日期中的小时【同时还有day,weekday等多个属性,按需使用】
# 最终 hour 这列存放的是当前订单下单的时间【小时】
data['hour'] = data['place_order_time'].map(lambda x:x.hour)
# 将 hour 一致的订单进行合并,令 hourcount 相加,即当前时间段下单的数量
gp_by_hour = data.groupby(by='hour').sum()['hourcount'].sort_values(ascending=False)
# 绘制柱状图
gp_by_hour.plot(kind='bar')
plt.xlabel('小时')
plt.ylabel('点菜数量')
plt.title('点菜数与小时的关系图')