内容简介

也不前情提要了,本博客内容高度概括就是:通过直接遍历法和依据文本法获取一个城市的“所有”线路名,并计算这些线路的平均路线长度、平均站点数、平均站距(“直线系数”将在下一篇博客中讨论)

正文

1、获取公交信息练习代码

(1)程序任务
通过高德地图PAI,爬取一个城市所有(可选)公交基本信息,并保存到表格中。采用循环遍历一定范围的数字实现,不封装函数(好处是,方便查看变量信息,及时发现错误,利于修改)

(2)可直接出结果的代码
遍历青岛前10路公交基本信息

import requests
import json
import pandas as pd
import timeif __name__=="__main__":t0=time.time()#用于记录开始时间bus_num=0  #计算有效遍历的公交数city='青岛' #需要查询公交信息的城市for_num=10 #遍历的线路数[1路,for_num路],通常公交线路数小于1000,具体可参考8684等网站all_bus=pd.DataFrame()for i in range(1,for_num+1):  line=str(i)+'路'try:#1、获取数据url = 'https://restapi.amap.com/v3/bus/linename?s=rsv3&extensions=all&key=a5b7479db5b24fd68cedcf24f482c156&output=json&city={}&offset=1&keywords={}&platform=JS'.format(city,line)r = requests.get(url).textrt = json.loads(r)#2、读取当前公交线路主要信息dt = {}dt['line_name'] = rt['buslines'][0]['name'] #公交线路名字dt['bounds'] = rt['buslines'][0]['bounds'] #行车区间(非始发站,终点站坐标)dt['distance'] = rt['buslines'][0]['distance'] #全程长度dt['station'] = int(rt['buslines'][0]['busstops'][-1]['sequence']) #全程站点数bus_num+=1 #有效公交数+1df2=pd.DataFrame(dt,index=[bus_num])  #返回pd.DataFrame()类型all_bus=pd.concat([all_bus,df2])  #不加这个'路'可能优先获取地铁except:print('没有{}公交'.format(line)) #正常情况下,这条语句不会执行print("Bus_info函数遍历{}前{}路公交,有效公交线路数为:{}个".format(city,for_num,bus_num))all_bus.to_csv("{}前{}路公交(有效线路数:{})基本信息.csv".format(city,for_num,bus_num),encoding='utf-8-sig')t1=time.time()#用于记录结束时间print("用时:%.2fs"%(t1-t0))

(3)程序结果:


(4)小结
大部分内容在之前的部分都介绍过了,这里获取站点数的代码值得好好品味一下(可以通过循环得到,但这样显得有些多余),啥也别说了,“数据就是程序员的生命”

dt['station'] = int(rt['buslines'][0]['busstops'][-1]['sequence'])

2、循环爬取公交信息(封装函数)

(1)程序内容介绍:
循环青岛市的1000路以内的公交(有的线路没有,且有的线路包含),获取这些线路的:路线名、行车区间、路程长度、站点数、区间直线距离等数据,并计算出这些公交线路的平均长度、平均站点数、平均站距,最后在python同目录下保存为表格。

(2)代码
小说明:我本意是希望大家拿我的代码就能出结果的,且不希望代码出现大的错误,但毕竟写的内容多了,改的地方也多,代码习惯也在培养的初期,加上生活中琐事也多,肯定是没精力做校对的,emmmmm,就这样

import requests
import json
import pandas as pd
import time
from math import sin, asin, cos, radians, fabs, sqrt#自己写的用于记录时间函数
def record_time(flag):if flag==0:global t0t0=time.time()else:t1=time.time()print("用时:%.2fs"%(t1-t0))  print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))#python计算两点间直线距离
def Geodistance(lng1,lat1,lng2,lat2):lng1, lat1, lng2, lat2 = map(radians, [lng1, lat1, lng2, lat2])dlon=lng2-lng1dlat=lat2-lat1a=sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2 dis=2*asin(sqrt(a))*6371*1000return dis#或许公交信息:线路名、始发站、终点站、行车区间(坐标)、路程、行车区间直线距离
def Bus_inf(city,line):global bus_num  #全局变量,用于计算公交数目try:#获取数据url = 'https://restapi.amap.com/v3/bus/linename?s=rsv3&extensions=all&key=a5b7479db5b24fd68cedcf24f482c156&output=json&city={}&offset=1&keywords={}&platform=JS'.format(city,line)r = requests.get(url).textrt = json.loads(r)#读取当前公交线路主要信息dt = {}dt['line_name'] = rt['buslines'][0]['name'] #公交线路名字dt['start_stop'] = rt['buslines'][0]['start_stop'] #始发站dt['end_stop'] = rt['buslines'][0]['end_stop'] #终点站dt['bounds'] = rt['buslines'][0]['bounds'] #行车区间(非始发站,终点站坐标)dt['distance'] = rt['buslines'][0]['distance'] #全程长度dt['station'] = int(rt['buslines'][0]['busstops'][-1]['sequence']) #全程站点数(包括始发站和终点站)lng1,lat1 =rt['buslines'][0]['bounds'].split(';')[0].split(',')lng2,lat2 =rt['buslines'][0]['bounds'].split(';')[1].split(',')dt['straight_dis'] =  Geodistance(float(lng1),float(lat1),float(lng2),float(lat2)) #计算行车区间bounds的直线距离bus_num+=1 #有效公交数+1return pd.DataFrame(dt,index=[bus_num]) #下标index为“第几条公交线”except:print('没有{}公交'.format(line)) #正常情况下,这条语句不会执行return pd.DataFrame()  #读取数据失败,返回空的def Bus_analysis(bus_info):#路程数据需要转float类型print('公交线路的平均长度:{:.6f} km'.format(bus_info["distance"].astype(float).mean())) print('公交线路的平均站点数:{:.6f} 个'.format(bus_info['station'].mean()))#错误站距求解方法:先求出每条线路的平均站距,相加,再除总线路数,得到的总的平均站距是不合适的!(涉及到加权问题)#站距求解方法1(不妥):平均长度/平均站点数  (这里的站点数包括了起始站和终点站,求平均站距时每条线路应该去掉一个站!)print('公交线路的平均站距(求法1)为:{:.6f} km/站'.format(bus_info["distance"].astype(float).mean()/bus_info['station'].mean()))#求站距方法2(正确):路线总长/(求出所有站点数总和-线路数)    print('公交线路的平均站距(求法2)为:{:.6f} km/站'.format(bus_info["distance"].astype(float).sum()/(bus_info['station'].sum()-bus_num)))if __name__=="__main__":record_time(0)bus_num=0  #设置全局变量数值(通常默认就是0)city='青岛' #需要查询公交信息的城市for_num=10 #遍历的线路数[1路,for_num路],通常公交线路数小于1000,具体可参考8684等网站all_buslines=pd.DataFrame()     for i in range(1,for_num+1):all_buslines=pd.concat([all_buslines,Bus_inf(city,str(i)+'路')])  #不加这个'路'可能优先获取地铁print("Bus_info函数遍历{}前{}路公交,有效公交线路数为:{}个的情况下:".format(city,for_num,bus_num))Bus_analysis(all_buslines)#all_buslines.to_csv("{}前{}路公交(有效线路数:{})基本信息.csv".format(city,for_num,bus_num),encoding='utf-8-sig')record_time(1)

(3)运行部分结果:
①424条公交线路


②10条线路情况

③如果只想知道市区线路呢?

3、获取已知线路名的公交信息

(1)说明
通过for循环获取公交线路名简单粗暴,但如果想知道定点区域的详细线路,或许就要一些别的方法了——通过8684网青岛公交获取市区所有路线名,保存到文本中。

(2)稍微修改的代码
直接拿来就能用的代码毕竟是少数啊~~~

import requests
import json
import pandas as pd
import time
from math import sin, asin, cos, radians, fabs, sqrt#自己写的用于记录时间函数
def record_time(flag):if flag==0:global t0t0=time.time()else:t1=time.time()print("用时:%.2fs"%(t1-t0))  print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))#python计算两点间直线距离
def Geodistance(lng1,lat1,lng2,lat2):lng1, lat1, lng2, lat2 = map(radians, [lng1, lat1, lng2, lat2])dlon=lng2-lng1dlat=lat2-lat1a=sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2 dis=2*asin(sqrt(a))*6371*1000return dis#或许公交信息:线路名、始发站、终点站、行车区间(坐标)、路程、行车区间直线距离
def Bus_inf(city,line):global bus_num  #全局变量,用于计算公交数目try:url = 'https://restapi.amap.com/v3/bus/linename?s=rsv3&extensions=all&key=a5b7479db5b24fd68cedcf24f482c156&output=json&city={}&offset=1&keywords={}&platform=JS'.format(city,line)r = requests.get(url).textrt = json.loads(r)dt = {}dt['line_name'] = rt['buslines'][0]['name'] #公交线路名字dt['bounds'] = rt['buslines'][0]['bounds'] #行车区间(始发站,终点站坐标)dt['distance'] = rt['buslines'][0]['distance'] #全程长度dt['station'] = int(rt['buslines'][0]['busstops'][-1]['sequence']) #全程站点数(包括始发站和终点站)lng1,lat1 =rt['buslines'][0]['bounds'].split(';')[0].split(',')lng2,lat2 =rt['buslines'][0]['bounds'].split(';')[1].split(',')dt['straight_dis'] =  Geodistance(float(lng1),float(lat1),float(lng2),float(lat2)) #计算行车区间bounds的直线距离#if '环形线' in dt['line_name']:#    print(dt['line_name'])bus_num+=1 #有效公交数+1return pd.DataFrame(dt,index=[bus_num]) #下标index为“第几条公交线”except:print('没有{}公交'.format(line)) #已知路线名的情况下,这条语句不会执行!return pd.DataFrame()  #读取数据失败,返回空的def Bus_analysis(bus_info):print('公交线路的平均长度:{:.6f}km'.format(bus_info["distance"].astype(float).mean())) print('公交线路的平均站点数:{:.6f}个'.format(bus_info['station'].mean())) #注意:这里的站点数包括了起始站和终点站,求平均站距时每条线路应该去掉一个站!#正确做法:路程/(求出所有站点数总和-线路数)print('公交线路的平均站距为:{:.6f}km/站'.format(bus_info["distance"].astype(float).sum()/(bus_info['station'].sum()-bus_num)))if __name__=="__main__":record_time(0)bus_num=0  #在已知文本的情况下,直接输出文本元素个数就是路线数,这里延续以前代码思路,故没修改all_buslines=pd.DataFrame()city='青岛市'#获取已知线路的公交文本with open("公交线路.txt", "r", encoding="utf-8") as f:bus_name = f.readlines()bus_name = bus_name[0].split(",") for i in bus_name:  all_buslines=pd.concat([all_buslines,Bus_inf(city,i)]) Bus_analysis(all_buslines)print("通过文本获取青岛市区{}条路线基本信息成功!".format(len(bus_name)))all_bus.to_csv("通过文本获取的青岛市区{}条路线基本信息.csv".format(len(bus_name)),encoding='utf-8')record_time(1)

(3)实验结果
对比前面全市找的424条线路(包括不少郊区线),市区线路的平均站距确实会短一点

4、多城市对比分析

直接遍历或许会有一些数据的缺失,但要是认真想想,这也可以当作是“随机取样”的过程,而且有的公交线路名字复杂,属于特殊线路,也算是排除异常数据了。
①北京

②突然不想分析了

对比分析见下一篇吧,加上“非直线系数”一块分析。

说明一下,我的这个系列博客很多地方是需要结合着一起来看的!


(补充知识)通过两点坐标求直线距离

地球是一个近乎标准的椭球体,它的赤道半径为6378.140千米,极半径为 6356.755千米,平均半径6371.004千米。如果我们假设地球是一个完美的球体,那么它的半径就是地球的平均半径,记为R。如果以0度经线为基准,那么根据地球表面任意两点的经纬度就可以计算出这两点间的地表距离。
按照0度经线的基准,东经取经度的正值(Longitude),西经取经度负值(-Longitude),北纬取90-纬度值(90- Latitude),南纬取90+纬度值(90+Latitude),那么根据三角推导,可以得到计算两点距离的如下公式:

其中lat1与lat2分别为两点的维度,lon1与lon2分别为两点的经度,6378为地球半径,计算的结果为千米,如果要的计算结果为米,在后面乘以1000即可。不过在写代码的时候要将经纬度的值转换为弧度。

def Geodistance(lng1,lat1,lng2,lat2):lng1, lat1, lng2, lat2 = map(radians, [lng1, lat1, lng2, lat2])dlon=lng2-lng1dlat=lat2-lat1a=sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2 dis=2*asin(sqrt(a))*6371*1000return dis

附件

青岛市区所有线路(注意时效性)

‘1路’,‘11路’,‘12路’,‘12路[区间]’,‘15路’,‘101路’,‘102路’,‘103路’,‘104路’,‘105路’,‘110路[区间]’,‘114路’,‘115路’,‘115路[区间]’,‘116路’,‘117路’,‘19路’,‘120路’,‘121路’,‘125路’,‘126路’,‘128路’,‘129路’,‘130路’,‘123路’,‘110路’,‘131路’,‘111路’,‘119路’,‘16路’,‘122路’,‘103路[定时快车]’,‘102路[定时快车]’,‘18路’,‘2路[汽车]’,‘2路[电车]’,‘20路’,‘21路’,‘22路’,‘23路’,‘24路’,‘25路’,‘26路’,‘28路’,‘29路’,‘205路’,‘206路’,‘207路’,‘208路’,‘209路’,‘210路’,‘213路’,‘214路’,‘215路’,‘216路’,‘218路’,‘219路’,‘220路’,‘221路’,‘222路’,‘223路’,‘224路’,‘225路’,‘226路’,‘227路’,‘228路’,‘229路’,‘230路’,‘231路’,‘232路’,‘233路’,‘216路[定时快车]’,‘3路’,‘30路’,‘31路’,‘32路’,‘36路’,‘302路’,‘303路’,‘304路’,‘307路’,‘308路’,‘310路’,‘312路’,‘313路’,‘314路’,‘316路’,‘317路’,‘318路’,‘319路’,‘320路’,‘321路’,‘322路’,‘361路’,‘362路’,‘363路’,‘364路’,‘326路’,‘366路’,‘367路’,‘368路’,‘369路’,‘370路’,‘371路’,‘372路’,‘373路’,‘374路’,‘375路’,‘378路’,‘381路’,‘380路’,‘379路’,‘382路’,‘385路’,‘325路’,‘383路’,‘384路’,‘386路’,‘387路’,‘327路’,‘363路[定时快车]’,‘318路[定时快车]’,‘363路[大站快车]’,‘318路[大站快车]’,‘302路[定时快车]’,‘313路[定时快车]’,‘321路[定时快车]’,‘374路[定时快车]’,‘388路’,‘389路’,‘390路’,‘4路’,‘405路’,‘403路’,‘402路’,‘401路’,‘461路’,‘462路’,‘463路’,‘465路’,‘407路’,‘408路’,‘409路’,‘410路’,‘466路’,‘411路’,‘467路’,‘468路’,‘469路’,‘470路’,‘412路’,‘413路’,‘406路’,‘404路’,‘414路’,‘471路’,‘415路’,‘5路’,‘501路’,‘503路’,‘502路’,‘503路[定时快车]’,‘605路’,‘610路’,‘611路’,‘612路’,‘613路’,‘616路’,‘615路’,‘618路’,‘619路’,‘620路’,‘621路’,‘623路’,‘622路’,‘625路’,‘629路’,‘630路’,‘627路’,‘631路’,‘632路’,‘626路’,‘628路’,‘633路’,‘635路’,‘636路’,‘614路’,‘624路’,‘637路’,‘639路’,‘638路’,‘640路’,‘641路’,‘634路’,‘642路’,‘643路’,‘644路’,‘7路’,‘761路’,‘765路’,‘762路’,‘763路’,‘766路’,‘767路’,‘769路’,‘770路’,‘771路’,‘772路’,‘768路’,‘773路’,‘774路’,‘775路’,‘772路[区间]’,‘779路’,‘777路’,‘778路’,‘8路’,‘901路’,‘902路’,‘903路’,‘904路’,‘905路’,‘908路’,‘906路’,‘907路’,‘909路’,‘910路’,‘912路’,‘913路’,‘915路’,‘916路’,‘917路’,‘919路’,‘929路’,‘930路’,‘921路’,‘920路’,‘922路’,‘923路’,‘924路’,‘925路’,‘918路’,‘926路’,‘927路’,‘928路’,‘932路’,‘931路’,‘933路’,‘935路’,‘936路’,‘937路’,‘938路’,‘934路’,‘939路’,‘941路’,‘942路’,‘914路’,‘944路’,‘940路’,‘943路’,‘都市观光1线’,‘都市观光4线’,‘高新快线’

【大数据】城市公交网络分析与可视化(五):获取公交平均路线长度、站点数、站距相关推荐

  1. 【大数据】城市公交网络分析与可视化(六):对比分析不同城市公交的“非直线系数”

    内容介绍 梗概:求一个城市的公交的平均(非)直线系数,并结合前面博客所求得的公交线路的平均长度.平均站点数.平均站距,对比分析几个城市的公交路线基本数据. 准备知识 1.什么是"非直线系数& ...

  2. 【大数据课程设计】城市公交网络分析与可视化(以青岛市为例)

    城市公交网络 城市公交网络分析与可视化 数据爬取与处理 公交站点信息爬取 公交线路轨迹爬取 坐标转换 城市公交网络可视化 利用ArcMap实现地图的可视化 利用plotly实现地图可视化 公交路线基本 ...

  3. 基于大数据的智能网络分析

    2018云栖大会深圳峰会弹性计算.网络和CDN专场上,阿里云高级技术专家云州给大家一起探讨了大数据的智能网络分析.通过介绍全球网络的超大规模,进而说明了智能网络齐天的设计必要性,着重详讲解了齐天智能网 ...

  4. Py之pyecharts:基于大数据对人工智能进行各种可视化图表分析

    pyecharts:基于大数据对人工智能进行各种可视化图表分析 目录 1. Bar(柱状图/条形图) 2 EffectScatter(带有涟漪特效动画的散点图) 3 .Funnel(漏斗图) 4.Ga ...

  5. 未来大数据的处理和发展的五个趋势

    本文讲的是未来大数据的处理和发展的五个趋势,近几年,大数据已经从大公司独有的流行词和概念变成了驱动我们数字生活发展的动力.下面是未来大数据的处理和发展的五个趋势. 1.数据科学越来越大众化 随着像Co ...

  6. 基于大数据的动漫影视可视化分析系统

    温馨提示:文末有 CSDN 平台官方提供的学长 Wechat / QQ 名片 :) 1. 项目简介 本动漫分析系统开发语言为Python,并进行数据清洗,数据处理,并最后利用可视化技术进行动漫数据分析 ...

  7. 一口气实现交通大数据爬取与Python可视化(含数据分享)

    今天的文章呢主要目的不是爬虫,而是爬虫的同时顺便实现实时可视化.上次爬摩拜单车数据的文章使用的是传统的ArcGIS进行自定义可视化,硬核 | Python多线程爬取摩拜单车数据与ArcGIS可视化,今 ...

  8. 大数据专业就业方向和考研院校及系统学习路线规划

    一.大数据的就业方向: 小标题 一.大数据专业的方向较多,以下是一些常见的方向: 1.数据挖掘与机器学习:主要关注数据的提取.处理.分析和预测,以及机器学习算法的应用. 2.大数据平台与分布式系统:主 ...

  9. 【大数据】城市公交网络分析与可视化(三):获取公交站点信息并可视化站点重要程度

    博客内容简介 通过前面的探究,我们大体知道如何获取一个城市的公交数据,并绘制了公交行驶路径散点图(效果不是很理想). 其实散点图感觉更适合类似于绘制公交站点这样的信息(行驶轨迹有其他更好的绘制技巧), ...

最新文章

  1. 语言舒尔特方格程序_注意力训练神器——舒尔特方格(成人、孩子均适用)
  2. python--异常处理
  3. P3292-[SCOI2016]幸运数字【线性基,LCA,倍增】
  4. 通过jQuery把数据库里面的数据进行增删查改
  5. pthread_join来接收线程的返回参数
  6. SpringBoot系列之使用自定义注解校验用户是否登录
  7. 转载:eclipse 搭建SSH项目(第二篇,有具体的项目例子)
  8. 一次JDBC与MySQL因“CST”时区协商误解导致时间差了13或14个小时
  9. 动易php,动易CMS数据转成dedecms的php程序
  10. layui实现简单分页
  11. wow3.13大脚插件
  12. 服务器系统补丁失败,windows server 2008更新补丁失败排错
  13. 如何获取应用宝APP ID
  14. Android客户端与PC服务器通过socket进行交互实例
  15. python多个函数_请教:一个类中可以定义多个同名函数?
  16. Additive secret sharing 加性秘密共享(加法,乘法,向量乘法)
  17. 题目;我们认为2是第一个素数,3是第二个素数,5是第三个素数,依次类推现在,给定两个整数n和m,你的程序要计算第n个素数到第m个素数之间所有的素数的和,包括第n个素数和第m个素
  18. 同步 fork(Syncing a fork)
  19. 区分bug 前后端归属之后,我再也不背锅了
  20. 喜欢士兵突击,我们都丢掉了,许三多没有丢

热门文章

  1. html动态网页作品,HTML5与CSS3实现动态网页
  2. [微语20.12.01] 心静
  3. python从入门到大师_Python趣味打怪:60秒学会一个例子,147段简单代码助你从入门到大师 | 中文资源...
  4. 岛屿的个数java_LeetCode 200:岛屿数量 Number of Islands
  5. 东莞横沥注塑模具设计与制造细节
  6. 写一个算法交换单链表中p所指结点与其后继结点-21算法题
  7. 一款可以实现淘宝拼多多虚拟店商品自动发货的百度网盘机器人软件助手
  8. SU插件情报局 | Fredo工具集:纹理工具(附插件安装包)
  9. Python:1018 锤子剪刀布
  10. 昨天在poco面试的一些回顾