【python数据分析实战】城市餐饮店铺选址问题(1)—— 对不同菜系进行比较,并筛选出可开店铺的餐饮类型

1. 首先将要使用的库全部进行导入,并设置程序运行路径

import os
os.chdir(r"C:\Users\86177\Desktop")
#设置路径
import pandas as pd
import matplotlib.pyplot as plt
#处理数据及绘图
import warnings
warnings.filterwarnings('ignore')
#忽略警报
from bokeh.io import output_file
from bokeh.plotting import figure,show
from bokeh.models import ColumnDataSource
#交互式处理

2. 数据导入并查看

data_load = pd.read_excel("上海餐饮数据.xlsx")
print(data_load.head(15))

–> 输出结果为:(选取前15条数据进行查看)
在这里插入图片描述
进行数据量以及标题信息的查看

print(df.columns.tolist())
print('总数据量为{}条'.format(len(df)))

–> 输出结果为:

['类别', '行政区', '点评数', '口味', '环境', '服务', '人均消费', '城市', 'Lng', 'Lat']
总数据量为96398

3. 不同类别评价指标的选择

通过表格输出可以发现,对于不同的菜系类别,可用的评价有’口味’, ‘环境’, ‘服务’, ‘人均消费’(‘点评数’也可以反映产品的受欢迎程度,但是其数据值比其他字段的对比要相差较多,而且其数据值本身波动范围较大),这里去掉’点评数’,添加一个‘性价比’字段的指标,假设:性价比 = (口味 + 环境 + 服务)/ 人均消费

data_filter = df[['类别', '口味', '环境', '服务', '人均消费']]
data_filter['性价比'] = (data_filter['口味'] + data_filter['环境'] + data_filter['服务']) / data_filter['人均消费']
data_filter.dropna(inplace = True)
data_filter = data_filter[(data_filter['口味']>0) & (data_filter['人均消费']>0)].reset_index()
del data_filter['index']
print(data_filter.head(15)

–> 输出结果为:(首先选取所需要的指标字段,然后获得性价比指标字段的数据;再处理缺失值,这两步可以调整顺序,最后的数据之差只有三条(先处理缺失值是54886条数据,后处理缺失值是54889条数据),其次将数据为0的行数处理掉,这里只要’口味’, ‘环境’, '服务’中一项为0,其他的都为0,所以只选择一项即可;最后重新设置索引并删除原索引)
在这里插入图片描述
4. 绘制箱型图查看异常数据

由于数据量较大,对于异常值的处理就很有必要,首先进行异常值的查看,可以使用箱型图进行描述,这里最终选择 三个指标 对不同菜系进行比较(当然也可以把‘服务’加进来)

fig, axes = plt.subplots(1,3,figsize = (14,6))
ls_columns = [ '口味', '人均消费', "性价比"]
for i in range(len(ls_columns)):
    data_filter.boxplot(column=ls_columns[i], ax = axes[i] )

–> 输出结果为:(这一部分就是matplotlib子图还有箱型图的绘制了,可以看到每个指标中都存在这大量的异常值)
在这里插入图片描述
5. 异常值数据的清洗工作

这里直接封装一个函数进行异常值的清洗,之后对于此类问题的处理可以直接进行函数的调用,而且处理各个字段的异常值应该分别进行处理,这样可以避免不同字段数据之间的影响

def f1(data,col):
    q1 = data[col].quantile(q = 0.25)
    q3 = data[col].quantile(q = 0.75) 
    iqr = q3-q1
    t1 = q1 - 3 * iqr
    t2 = q3 + 3 * iqr
    return data[(data[col] > t1)&(data[col]<t2)][['类别',col]]

data_kw = f1(data_filter,'口味')
data_rj = f1(data_filter,'人均消费')
data_xjb = f1(data_filter,'性价比')

使用iqr进行异常值的清洗,今后可以直接进行函数的调用,只需要修改一下‘类别’的信息即可

6. 数据标准化并排序

数据异常值处理完毕之后,标准化处理,还是一样直接封装函数,方便之后直接调用,依旧是对不同的数据进行标准化

def f2(data,col):
    col_name = col + '_norm'
    data_gp = data.groupby('类别').mean()
    data_gp[col_name] = (data_gp[col] - data_gp[col].min())/(data_gp[col].max()-data_gp[col].min())
    data_gp.sort_values(by = col_name, inplace = True, ascending=False)
    return data_gp

data_kw_score = f2(data_kw,'口味')
data_rj_score = f2(data_rj,'人均消费')
data_xjb_score = f2(data_xjb,'性价比')

标准化的基本步骤:首先创建一个新字段(列)并命名,然后按照某个要求进行分组(为什么取均值可以想一下,这个要回顾上一步异常值处理后的数据的结果),接着按照分组后的数据使用‘最大’/‘最小’标准化,最后进行某个字段(一般是某个标准化后的字段)进行排序即可

7. 数据合并与绘图前准备

经过异常值清洗和标准化处理,数据已经可以进行使用了。接着就是将分开处理的数据再合并在一起,因为存在三组数据,所以应该是两两合并(索引的标签都是餐馆的类型)

data_final_q1 = pd.merge(data_kw_score,data_rj_score,left_index=True,right_index=True)    # 首先合并口味、人均消费指标得分
data_final_q1 = pd.merge(data_final_q1,data_xjb_score,left_index=True,right_index=True)       # 接着合并性价比指标得分
print(data_final_q1.head(15))

–> 输出结果为:
在这里插入图片描述
使用bokeh绘图之前,需要将columns的数据设置为英文(index这一列的名称也要是英文),另外设置一下点的大小(size参数)

data_final_q1['size'] = data_final_q1['口味_norm'] * 40  # 添加size字段
data_final_q1.index.name = 'type'
data_final_q1.columns = ['kw','kw_norm','price','price_norm','xjb','xjb_norm','size']

8. 出图

from bokeh.layouts import gridplot
from bokeh.models import HoverTool
from bokeh.models.annotations import BoxAnnotation

output_file('菜系类型.html')#输出文件
source = ColumnDataSource(data_final_q1)#创建数据
data_type = data_final_q1.index.tolist()#横坐标为index,要先转化为列表

hover = HoverTool(tooltips = [
    ('餐饮类型','@type'),
    ('人均消费','@price'),
    ('性价比得分','@xjb_norm'),
    ('口味得分','@kw_norm'),
])

result = figure(plot_width = 800,plot_height = 300,title = '餐饮类型得分',
				x_axis_label = '人均消费', y_axis_label = '性价比',
               tools = [hover, 'box_select, reset, xwheel_zoom,pan,crosshair'])
result.circle(x = 'price', y = 'xjb_norm', source = source,
			line_color ='black',line_dash =[6,4], fill_alpha =0.6,size = 'size')

price_mid = BoxAnnotation(left = 40, right = 80, fill_alpha = 0.1, fill_color = 'navy')
result.add_layout(price_mid)#这里设置标记区


kw = figure(plot_width = 800,plot_height = 300,title = '口味得分',x_range = data_type,
               tools = [hover, 'box_select, reset, xwheel_zoom,pan,crosshair'])
kw.vbar(x = 'type', top = 'kw_norm', source = source, width = 0.8, alpha = 0.7,color = 'red')

price = figure(plot_width = 800,plot_height = 300,title = '人均消费得分',x_range = data_type,
               tools = [hover, 'box_select, reset, xwheel_zoom,pan,crosshair'])
price.vbar(x = 'type', top = 'price_norm', source = source, width = 0.8, alpha = 0.7,color = 'green')

p = gridplot([[result],[kw],[price]])#将三个图放在一个画布上

show(p)#一定要加show(p),否则不显示

–> 输出结果为:(可以看出选择素菜馆较为合理,在标定的范围区间内,最大的气泡图就为素菜类型)
在这里插入图片描述

  • 5
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lys_828

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值