1. 选址的评价指标如下:
人口密度指标 → 得分越高越好
道路密度指标 → 得分越高越好
餐饮热度指标 → 得分越高越好
同类竞品指标 → 得分越低越好
综合指标 = 人口密度指标x0.4 + 餐饮热度指标x0.3 + 道路密度指标x0.2 +同类竞品指标x0.1(假定)
2. 需要的空间数据(全是投影坐标系)
上海行政区:net_population.shp (上海1km²格网内的人口密度数据)
具体的道路:road.shp (上海道路数据)
网格数据:需要后面自己划分设定
在qgis
做空间统计之后,网格数据导出点数据,投影成wgs84
地理坐标系,导出excel
文件
3. 指标处理
1)人口密度指标:对应net_population.shp中的数据,打开qgis,通过导入的该文件,双击进入‘样式’,选择‘渐进’,Z字段进行‘分位数’分类,然后点击‘应用’,就得到了要求的结果
–> 输出结果为:
2)道路密度指标: 就是网格数据除以网格类的道路长度,选择菜单栏‘矢量’下面的‘分析工具’,点击‘计算线条总长度,这时候要新建一个文件夹来保存创建的数据文件,这样会计算每个网格里面的道路长度,并生成一个新的画布new_result(建议不要和原来的名称一样),打开属性表后,可以在’Z’值后增加了一个‘长度’列
–> 输出结果为:
3)餐饮热度指标:加载餐饮数据.csv文件,编码默认GBK,然后选择横纵坐标,这时候加载的时候选择是WGS84的坐标系,如果直接使用投影坐标系,则该数据和地图数据不再一块。然后在将导入的数据转化为投影坐标系,这时候右键导入的数据,‘另存为’,选择投影坐标系,输入好文件名称(这里命名为cy)后,存在上一步创建好的文件夹里就可以了
–> 输出结果为:
计算网格里餐饮店的个数,选择菜单栏上的‘矢量’,‘分析工具’,然后点击‘计算多边形内点的数目’,这时候‘输入多边形矢量图层’选择完成道路密度指标时候创建的新的画布new_result,'输入的点矢量’就是刚刚加载的cy数据,这时候属性聚合的统计方法选择‘总计’,输出的字段保存为cy_count,画布名称为new_result2,这时候属性表里面就多了一列‘cy_count’的数据
–> 输出结果为:
4)同类竞争指标:针对cy的数据,打开属性表做一个选择,打开表达式选择‘字段和值’下面的类别(双击),在左侧窗口点击‘=’,之后在右下点击全部唯一,找到‘素菜’,并双击。然后重新打开属性表,可以看到上方有个’已选中178
–> 输出结果为:
这时候点击左下角的‘显示所有要素’,这时候将cy数据另存为,注意勾选‘仅保存选中的要素’,命名为sc,投影坐标系。然后计算网格中素菜馆的个数,按照上一步骤重复一下即可(这里的输入多边形矢量图层选择new_result2,,输入的点矢量就是刚刚加载的sc数据),最终的画布new_result3就是最终的数据了
–> 输出结果为:
最后:将网格转变为多边形质心(点),选择‘矢量’,‘集合工具’,点击‘多边形质心’,输入层选择new_result3,输出的文件名称为result_point,这时候要添加lng和lat,要将投影坐标系再转回到wgs84坐标系中,点击另存为,选择wgs84坐标系后,保存文件result_point_wgs84,这时候打开属性表,新建字段,分别创建lng、lat,都选择小数(浮点型),分别对应几何图形里面的$x, $y.至此所有的处理工作完成,导出数据就行,新建一个Excel表格,ctrl + a 键全选qgis里面的数据粘贴到Excel表格里面就可以了,第一列删掉,然后保存在桌面。数据样式如下:(直截取部分)
–> 输出结果为:
4. python数据处理
1)数据导入并查看
加载刚刚通过qgis处理过后的数据
df2 = pd.read_excel('data.xlsx')
data_df2_count = len(df2)
print('一共有的数据量为{}'.format(data_df2_count))
print(df2.head())
–> 输出结果为:
一共有的数据量为7222
人口密度 道路长度 餐饮计数 素菜餐饮计数 lng lat
0 20666 13427.636733 1205.0 13.0 121.441774 31.228846
1 20666 10871.020833 632.0 9.0 121.441922 31.219827
2 36929 12104.466337 972.0 4.0 121.452417 31.219953
3 38393 11489.521043 346.0 4.0 121.441477 31.246885
4 12314 12615.408243 231.0 4.0 121.504325 31.256653
2) 缺失值查看以及处理
print(df2.isna().sum())
–> 输出结果为:
Z 0
长度 0
cy_count 4896
sc_count 7114
lng 0
lat 0
dtype: int64
可以发现sc_count(也就是素菜馆的数量)字段缺失数据严重,因为就是给素菜馆选址,所以符合要求的地点很少,那么对缺失的数据这里不可能全部删除,这里使用0进行填补缺失值,并对数据的字段名称进行修改
df2.fillna(0, inplace= True)
df2.columns = ['人口密度','道路长度','餐饮计数','素菜餐饮计数','lng','lat']
print(df2.head(15))
–> 输出结果为:
3)指标标准化
df2['rkmd_norm'] = (df2['人口密度'] - df2['人口密度'].min())/(df2['人口密度'].max() - df2['人口密度'].min())
df2['cyrd_norm'] = (df2['餐饮计数'] - df2['餐饮计数'].min())/(df2['餐饮计数'].max() - df2['餐饮计数'].min())
df2['scjp_norm'] = (df2['素菜餐饮计数'].max() - df2['素菜餐饮计数'])/(df2['素菜餐饮计数'].max() - df2['素菜餐饮计数'].min())
df2['dlmd_norm'] = (df2['道路长度'] - df2['道路长度'].min())/(df2['道路长度'].max() - df2['道路长度'].min())
df2['finial_score'] = df2['rkmd_norm']*0.4 + df2['cyrd_norm']*0.3 +df2['scjp_norm']*0.1+df2['dlmd_norm']*0.2
data_final_q2 = df2.sort_values(by='finial_score',ascending = False).reset_index()
del data_final_q2['index']
–> 输出结果为:(注意素菜/同类竞品指标采用的是最小标准化,其余的都是最大标准化,注意区别)
4) 绘制空间散点图,确定具体位置
#单独确定散点图的大小
data_final_q2['size'] = data_final_q2['finial_score'] * 20
data_final_q2['color'] = 'green'
data_final_q2['color'].iloc[:20] = 'red'#设置好颜色后,再将前二十位的设置成为重要颜色,顺序不能反了
source = ColumnDataSource(data_final_q2)
output_file('餐馆地址.html')
hover = HoverTool(tooltips = [
('经度','@lng'),
('纬度','@lat'),
('最终得分','@finial_score'),
])
p = figure(plot_width = 800,plot_height = 800,title = '空间散点图',
tools = [hover, 'box_select, reset, wheel_zoom,pan,crosshair'])
p.square(x = 'lng',y ='lat',source = source,line_color = 'black',line_dash =[6,4],fill_alpha = 0.8, color = 'color',size = 'size')
show(p)
–> 输出结果为:(注意lng,lat是不能取整的了,否则就得不到需要的位置数据)