Project 2 : 北京地铁数据处理及路径探寻
完成北京地铁路线搜寻
使用搜寻策略完成如下项目:接收两个北京地铁站站点,得到两个站点间的优化路径。
Please using the search policy to implement an agent. This agent receives two input, one is @param start station and the other is @param destination. Your agent should give the optimal route based on Beijing Subway system.
思路:
一、首先我们需要获取数据:
数据源大概分为四类:
- 公开开放的数据集,如《统计年鉴》等。
- 可以爬取的网页数据,如,网站内容或者APP内容等,注意robots协议。
- 传感器数据,如无人驾驶汽车雷达采集信息等,一般是物理信息。
- 日志信息,用于统计用户的操作,可以前端埋点收集或者后端脚本收集及统计,以统计网站的访问情况及瓶颈等,如网站上一个商品的点击率数据。
二、数据清洗:
- 使用正则表达式,获取站点信息和路线信息
- 将以上信息整理成可使用的数据结构
三、完成路径探寻:
- 广度优先搜索、宽度优先搜索
Python爬虫工具
爬虫工具有两类:一类为可视化工具,以八爪鱼和火车头为代表。特点速度快,模板多,但不全面不够个性化。
另一类为Python爬虫工具,Beautiful Soup and Selenium;Selenium主要用于模拟人的操作。两者均可以自定义爬取内容。
要想得到北京市地铁站及线路信息,要想直接从官网获取,并不容易,需要大量的使用正则表达式。
这里我们可以从高德地图等网站,找到地铁的 json 数据直接调用,json 格式是标准的字典格式。
高德地铁图网站:http://map.amap.com/subway/index.html
subway:http://map.amap.com/service/subway_1599542108002&srhdata=1100_drw_beijing.json
可以看到 json字符串 是标准的字典格式。直接爬取此网站即可获得地铁站及线路信息。
Re正则表达式
import re
r"" 表示为⼀个正则表达式
pattern = r"[1-9][0-9]{4,}"
m = re.findall(pattern, '这是我的QQ号781504542,第二个qq号:10054422288')
print(m) if m is not None else print('None')
字符 | 描述 |
---|---|
\ | 将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。例如,“n”匹配字符“n”。“\n”匹配一个换行符。串行“\”匹配“\”而“(”则匹配“(”。 |
^ | 匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。 |
* | 匹配前面的子表达式零次或多次。例如,zo*能匹配“z”以及“zoo”。* 等价于{0,}。 |
+ | 匹配前面的子表达式一次或多次。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。 |
? | 匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“does”或“does”中的“do”。?等价于{0,1}。 |
{n} | n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。 |
{n,} | n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。 |
{n,m} | m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”将匹配“fooooood”中的前三个o。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。 |
? | 当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o+”将匹配所有“o”。 |
. | 匹配除“\n”之外的任何单个字符。要匹配包括“\n”在内的任何字符,请使用像“(. |
(pattern) | 匹配pattern并获取这一匹配。所获取的匹配可以从产生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中则使用 0… 9属性。要匹配圆括号字符,请使用“(”或“)”。 |
(?:pattern) | 匹配pattern但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用或字符“( |
(?=pattern) | 正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,“Windows(?=95 |
(?!pattern) | 正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如“Windows(?!95 |
(?<=pattern) | 反向肯定预查,与正向肯定预查类拟,只是方向相反。例如,“(?<=95 |
(?<!pattern) | 反向否定预查,与正向否定预查类拟,只是方向相反。例如“(?<!95 |
x|y | 匹配x或y。例如, “z|food”能匹配“z”或“food”。“(z|f)ood”则匹配“zood”或“food”。 |
[xyz] | 字符集合。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。 |
[ ^xyz ] | 负值字符集合。匹配未包含的任意字符。例如,“[^abc]”可以匹配“plain”中的“p”。 |
[a-z] | 字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。 |
[ ^a-z ] | 负值字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。 |
\b | 匹配一个单词边界,也就是指单词和空格间的位置。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。 |
\B | 匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。 |
\cx | 匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的“c”字符。 |
\d | 匹配一个数字字符。等价于[0-9]。 |
\D | 匹配一个非数字字符。等价于[^0-9]。 |
\f | 匹配一个换页符。等价于\x0c和\cL。 |
\n | 匹配一个换行符。等价于\x0a和\cJ。 |
\r | 匹配一个回车符。等价于\x0d和\cM。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。 |
\S | 匹配任何非空白字符。等价于[^ \f\n\r\t\v]。 |
\t | 匹配一个制表符。等价于\x09和\cI。 |
\v | 匹配一个垂直制表符。等价于\x0b和\cK。 |
\w | 匹配包括下划线的任何单词字符。等价于“[A-Za-z0-9_]”。 |
\W | 匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。 |
\xn | 匹配n,其中n为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,“\x41”匹配“A”。“\x041”则等价于“\x04&1”。正则表达式中可以使用ASCII编码。. |
\num | 匹配num,其中num是一个正整数。对所获取的匹配的引用。例如,“(.)\1”匹配两个连续的相同字符。 |
\n | 标识一个八进制转义值或一个向后引用。如果\n之前至少n个获取的子表达式,则n为向后引用。否则,如果n为八进制数字(0-7),则n为一个八进制转义值。 |
\nm | 标识一个八进制转义值或一个向后引用。如果\nm之前至少有nm个获得子表达式,则nm为向后引用。如果\nm之前至少有n个获取,则n为一个后跟文字m的向后引用。如果前面的条件都不满足,若n和m均为八进制数字(0-7),则\nm将匹配八进制转义值nm。 |
\nml | 如果n为八进制数字(0-3),且m和l均为八进制数字(0-7),则匹配八进制转义值nml。 |
\un | 匹配n,其中n是一个用四个十六进制数字表示的Unicode字符。例如,\u00A9匹配版权符号(©)。 |
广度优先搜索(BFS)、宽度优先搜索(DFS)
BFS使用队列的思想,先进先出;DFS使用栈的思想,后进先出。
BFS:宽度优先,首先搜索全部子节点,完成后搜索全部子节点的全部子节点。
DFS:深度优先,一条道走到黑,先在左节点上全部走完,然后回退。
本题中:由于每条线路的地铁站众多,但每一个地铁站的相邻节点最多只有四个,所以 DFS 的时间与空间复杂度均高与 BFS 。
流程
一、数据加载:
import requests
import re
r = requests.get('http://map.amap.com/service/subway?_1469083453978&srhdata=1100_drw_beijing.json')
print('文本编码:',r.encoding)
print('相应状态码:',r.status_code)
print('字符串方式响应体:',r.text)
#使用json解析
import json
import pandas as pd
bj_s = json.loads(r.text)
bjs = pd.DataFrame(bj_s)
bjs.head()
二、数据预处理
#获取地铁线路信息
#获取站点名称n
#获取经纬度信息sl
pattern_kn = r'"kn":"(\w+)"|"n":"(\w+)"'
pattern_n = r'"n":"(\w+)"'
pattern_sl = r'"sl":"(\d+\.\d+,\d+\.\d+)"'
line = re.findall(pattern_kn,r.text)
#print(line)
name = re.findall(pattern_n,r.text)
#print(name)
location = re.findall(pattern_sl,r.text)
#print(location)
构建站点名称和经纬度的字典
#构建站点名称和经纬度的字典
station_info = {}
for i in range(len(name)):station_info[name[i]] = tuple(map(float,location[i].split(',')))
#print(station_info.values())
station_df = pd.DataFrame(station_info)
station_df2 = pd.DataFrame(station_df.values.T,index = station_df.columns,columns = station_df.index)
print(station_df2.head)
line_info = {}
li = list()
for j in line:if j[0] =='':li.append(j[1])else:line_info[j[0]] = lili = list()
print(line_info)
建立邻接链表dic
#建立邻接链表dic
line_list = list(line_info)
#print(line_list)
already_check = list()
connection = {}
for g in line_list:for h in range(len(line_info[g])):if line_info[g][h] not in already_check:if 0<h<len(line_info[g])-1:connection[line_info[g][h]] = [line_info[g][h-1],line_info[g][h+1]]if h == 0:connection[line_info[g][h]] = [line_info[g][h+1]]if h == len(line_info[g])-1:connection[line_info[g][h]] = [line_info[g][h-1]]already_check.append(line_info[g][h])else:if 0<h<len(line_info[g])-1:connection[line_info[g][h]] += [line_info[g][h-1],line_info[g][h+1]]if h == 0:connection[line_info[g][h]].append(line_info[g][h+1])if h == len(line_info[g])-1:connection[line_info[g][h]].append(line_info[g][h-1])print(connection['宋家庄'])
三、绘制地铁分布图
import networkx as nx
import matplotlib.pyplot as plt
from pylab import mpl# 指定默认字体,解决不显示中文
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False plt.figure(figsize=(30,30))
station_info.keys()
#print(station_info.keys())
station_graph = nx.Graph()
station_graph.add_nodes_from(list(station_info.keys()))
nx.draw(station_graph,station_info,with_labels=True,nodes_size=30)plt.figure(figsize=(30,30))
station_network = nx.Graph(connection)
nx.draw(station_network,station_info,with_labels=True,node_size=30)
四、使用广度优先算法得到路径
#定义距离函数
def search_path (graph,start,destination):already_check = []#存放检查过的点dic = {}#存放检查过的node的prestationexpand = [start]#存放需要检查的点if start not in graph:print(0)return if destination not in graph:return if graph[start] == []:print(1)return while expand:node = expand.pop(0)if node == destination: return path(start,destination,dic,the_path=[])if node in already_check:continueelse:neighbor = []already_check.append(node)neighbor = graph[node]for i in neighbor:if i in already_check: continuedic[i] = node#print(dic)expand += neighborcontinuedef path (initial,value,dic,the_path=[]):if value == initial:the_path.append(initial)return the_pathvalue1 = dic[value]the_path.append(value)return path(initial,value1,dic,the_path)list = []
list = search_path(connection,'天宫院','宋家庄')
list.reverse()
print(list)
[‘天宫院’, ‘生物医药基地’, ‘义和庄’, ‘黄村火车站’, ‘黄村西大街’, ‘清源路’, ‘枣园’, ‘高米店南’, ‘高米店北’, ‘西红门’, ‘新宫’, ‘公益西桥’, ‘角门西’, ‘角门东’, ‘大红门’, ‘石榴庄’, ‘宋家庄’]
Project 2 : 北京地铁数据处理及路径探寻相关推荐
- WPF简易北京地铁效果图
这个是百度地图上北京地铁的地址http://map.baidu.com/?subwayShareId=beijing,131,我们先看下百度上面的效果图 我要实现的内容比较简单,就是绘制这些图,和在地 ...
- 北京地铁票价查询系统 c++ Dijkstra算法
包含一号线.二号线全部,还有两小段 数据来自北京地铁官网 资源链接 https://download.csdn.net/download/renzemingcsdn/44352688 #include ...
- WPF 实现简易北京地铁效果图
本文经原作者授权以原创方式二次分享,欢迎转载.分享. 原文作者:眾尋 原文地址: https://www.cnblogs.com/ZXdeveloper/p/8600785.html 前言 这个是百度 ...
- java实现北京地铁换乘
文章目录 项目GitHub地址 文件存放 station.txt 设计思路与模块分析 Station.java DataBuilder.java StationIncludeLineName.java ...
- 3天初版部署7天快速迭代!百度飞桨携手北京地铁落地AI口罩检测方案
允中 发自 凹非寺 量子位 报道 | 公众号 QbitAI 百度AI抗疫,又有新方案部署落地.这次,事关企业复工后,持续升级的公共交通防疫战. 近日,针对北京地铁防疫需求,百度与北京地铁合作开展了A ...
- 涨姿势!北京地铁原来是16条旅游专线
学姐按:周末想带孩子玩,又没太多时间.好不容易有时间出去了,结果半天都被堵在了路上,这让很多家长每逢周末必发愁.为什么不换种方式出行呢?北京的地铁的里程越来越长,殊不知所经之处有很多的大小景点可以玩. ...
- 北京地铁线路图纯算法附带求极权值(原创) 性能提升版
先上一张大家都看过而且熟悉的北京地铁线路图: 其中本人由于时间时间问题所以就写入了:昌平线,1,2,4,5,6,8,10,13共9条线路图: 接下来我说说我的思路 我的思路是这样的: 首先定义变量b, ...
- oracle多条数据合并成一条_建议将北京地铁13-B线和28号线合并成一条线
由于之前北京地铁规划的28号线是一条核心区市区短线,长度仅为9公里.而地铁作为轨道交通应该是优先承担长距离乘客运输任务,可以说不到万不得已,最好不要规划这样的过短线路.又因为地铁13号线拆分后,拆分后 ...
- 地铁系统_北斗授时助力北京地铁地下定位系统
北京地铁建设城市轨道交通定位系统 据统计,人们80%以上的时间在建筑物.地下.室内等非暴露空间中度过.地铁作为非暴露空间的典型场景,是智慧城市建设中最核心的公共区域,聚集了各类人员,拥有较大的影响面. ...
最新文章
- python列出文件夹所有文件_python-列出所有目录及子目录文件
- cuda-convnet2编译
- Spartan-II 应用指南 转载
- org.apache.ibatis.reflection.ReflectionException: Error instantiating class with invalid types
- codeforces——Little Pony and Sort by Shift
- android sdk manager 更新失败
- 服务器文档读取不了,服务器读取不到内存
- Windows 命令行及Git操作
- 正则系列之手机号码正则
- Digispark ATtiny85 单片机点灯大师之圣诞节彩灯Merry Christmas
- 招银网络科技Java社招面经
- 【测试记录】基于pdf论文提取论文doi—pdf2doi包的安装与使用
- SSM 校园外卖系统的设计与实现
- JQ设置cookie(3分钟搞定)
- no diagrams overlap selections问题解决
- 生成10位由大小写字母和数字组成的随机激活码
- arduino与801s振动传感器读取振动频率
- 系统的进程号PID的了解
- 时间序列预测(2):AI助力精准气象和海洋预测
- GB/T25915.1法规基本标准-附 录 B(资料性)等级划分计算