博客內容說明
本博客爲系列課題第二篇,一些必要的內容請見:
【大數據】城市公交網絡分析與可視化(一):藉助Python爬取公交車行駛路徑等基本信息
本博客內容簡介:藉助高德地圖API,爬取一個城市多條公交線路軌跡座標,並繪製公交行駛路徑(散點)圖。(本博客以青島舉例,並依次繪製10條線路、49條線路、全部線路)
具體探究過程
運行環境:Anaconda 中的Spyder軟件
1、青島市1路到10路公交運行路線(軌跡)
(1)直接可運行代碼
確實有可能出現我這裏運行的好好的,但他處不能運行的情況,emmmmm,祝你好運!
import requests
import json
import pandas as pd
def get_line(cityname,line,path):
#獲取數據
url = 'https://restapi.amap.com/v3/bus/linename?s=rsv3&extensions=all&key=a5b7479db5b24fd68cedcf24f482c156&output=json&city={}&offset=1&keywords={}&platform=JS'.format(cityname,line)
r = requests.get(url).text
rt = json.loads(r)
try:#若報錯(即該沒有線路)進入except,跳過
polyline=rt['buslines'][0]['polyline'] #獲取沿途路徑座標
path=path+polyline #這裏通過path字符串累計獲取所有公交線路路徑
return path
except:
print('沒有{}路公交'.format(line))
pass
if __name__=="__main__":
path_str=''
for i in range(1,11):
path_str=get_line('青島',str(i),path_str)
print(len(path_str)) #獲取座標字符串總長度(不是座標總數,總數大約爲這個數/21)
path={}
path['station_coords']=path_str.split(";") #通過";"拆分每個路徑座標
path=pd.DataFrame(path)
#將座標拆解爲經度longitude,和緯度latitude(請根據具體使用場景處理數據)
path['longitude'],path['latitude'] = path['station_coords'].str.split(',', 1).str
path.to_csv('青島10條線路公交路線軌跡數據.csv',encoding='utf-8')
#path.drop(['station_coords'],axis=1,inplace=True) #狡兔死走狗烹,飛鳥盡良弓藏 經度,緯度提取出來,可以把原來的經緯度給刪了
#path.to_csv('青島10條線路公交路線軌跡數據.csv',index=False,encoding='utf-8-sig') #index=False即不顯示index索引
(2)運行結果:
(3)刪除一些不必要數據後的結果
這裏處理是爲了節省空間的情況下便於後面高德地圖繪製,本來只需要一列經緯度就好了,我也按照高德地圖要求去處理數據了,就是不行,很迷,遂放棄,兩列就兩列吧。
不行!!!
不知出於什麼原因,刪除座標列,繪圖平臺讀取數據不成功!
只好加回來了。
(繼續看,後面有些問題原因)
(4)可視化
如何知道我獲取的路徑數據是對的?
那就畫出來吧!高德開發平臺(Map Lab)
2、青島市1路到50路(無44路)公交運行路線(軌跡)
(1)上面代碼的修改版
import requests
import json
import pandas as pd
import time
def get_line(cityname,line,path):
#獲取數據
url = 'https://restapi.amap.com/v3/bus/linename?s=rsv3&extensions=all&key=a5b7479db5b24fd68cedcf24f482c156&output=json&city={}&offset=1&keywords={}&platform=JS'.format(cityname,line)
r = requests.get(url).text
rt = json.loads(r)
try:#若報錯(即該沒有線路)進入except,跳過
polyline=rt['buslines'][0]['polyline'] #獲取沿途路徑座標
path=path+polyline #這裏通過path字符串累計獲取所有公交線路路徑
return path
except:
print('沒有{}路公交'.format(line))
#pass
return path #之前寫pass,因爲這個函數是有返回值的,故行不通
if __name__=="__main__":
#獲取1路到50路公交的量較大,或許需要個計時器
t0=time.time()
print('顯示程序開始的時間:',time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))
path_str=''
for i in range(1,51):
path_str=get_line('青島',str(i),path_str)
path={}
path['station_coords']=path_str.split(";") #通過";"拆分每個路徑座標
path=pd.DataFrame(path)
path.to_csv('青島50條線路公交路線軌跡數據.csv',index=False,encoding='utf-8') #index=False即不顯示index索引
print("座標數據有{}條".format(len(path['station_coords'])))
t1=time.time()
print('顯示程序結束的時間:',time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))
print("用時:%.6fs"%(t1-t0))
(2)運行結果:
(3)獲取的表格數據
也不知道啥原理,這次只放一個座標數據,也不要按要求那樣加引號高德地圖也能讀取了!
(4)那就數據可視化嘍
49條公交線路,15983個座標軌跡,已經很卡了😂
接下來,該幹嘛,大家應該猜到了
3、青島市所有公交(遍歷1000路公交)運行軌跡!
(1)本質沒變的代碼:
import requests
import json
import pandas as pd
import time
def get_line(cityname,line,path,bus_num):
#獲取數據
url = 'https://restapi.amap.com/v3/bus/linename?s=rsv3&extensions=all&key=a5b7479db5b24fd68cedcf24f482c156&output=json&city={}&offset=1&keywords={}&platform=JS'.format(cityname,line)
r = requests.get(url).text
rt = json.loads(r)
try:
polyline=rt['buslines'][0]['polyline']
path=path+polyline #這裏通過path字符串累計獲取所有公交線路路徑
return bus_num+1,path
except:
print('沒有{}路公交'.format(line))
return bus_num,path
if __name__=="__main__":
t0=time.time()#記錄時間用的
path_str=''
bus_num=0 #基本功沒學好,關於python全局變量和傳參問題一直搞得不清楚,所有采用比較撈的方法獲取局部變量數據變化了
for i in range(1,1001):
bus_num,path_str=get_line('青島',str(i),path_str,bus_num)
path={}
path['station_coords']=path_str.split(";")
path=pd.DataFrame(path)
path.to_csv('青島所有線路(循環1000路實現)公交路線軌跡數據.csv',index=False,encoding='utf-8')
print("座標數據有{}條".format(len(path['station_coords'])))
print('遍歷了{}條公交線路'.format(bus_num))
t1=time.time()
print("運行用時:%.2fs"%(t1-t0))
(2)實驗結果
做過大數據項目的人應該知道,6分半運行時間還是能接受的!
遍歷了424條公交線路可還行!
現在的問題是:136776條座標數據!
爲此我還專門查了:“Excel 2013版:列數最大16384(2的14次方),行數最大1048576(2的20次方)”
Execl是沒問題了,高德地圖傳不上去呀!!!
(3)做人要有夢想——補充代碼
不讓上傳超過5萬行的數據,最多能上傳3個表格,有13多萬條數據!
真実は一つだけです!
path.iloc[0:49000, :].to_csv('青島所有線路(循環1000路實現)公交路線軌跡數據-拆分數據1.csv',index=False,encoding='utf-8')
path.iloc[49000:98000, :].to_csv('青島所有線路(循環1000路實現)公交路線軌跡數據-拆分數據2.csv',index=False,encoding='utf-8')
path.iloc[98000:, :].to_csv('青島所有線路(循環1000路實現)公交路線軌跡數據-拆分數據3.csv',index=False,encoding='utf-8')
順帶一說,我好像知道爲什麼最開始只直接上傳座標數據,高德讀取不了,後來又可以了:不可以是因爲加了索引;保存數據的時候加“index=False”,去掉索引就好了!
(4)分三次上傳的數據繪製的結果!
①上傳第一部分數據(黃色部分)
此時我的電腦,明顯感到勉爲其難了,每操作一下電腦風扇就瘋狂地在抱怨~
②上傳第二部分數據(藍色部分)
卡成PPT!!!
③上傳第三部分數據(紅色部分)
每一次操作都會伴隨漫長的等待,2年半以前的筆記本究落伍了。(當然本身這個數據量這麼大處理有問題是能理解的),突然理解爲什麼那麼多專業款的電腦那麼貴了,1.5TB內存頂配 Mac pro瞭解一下
其實三種顏色也是有一定含義的,黃色表示該公交“路數”比較小(大約1路-200路左右),藍色表示該公交“路數”中等(大約200路-500路),紅色表示“路數偏大”(大約500路-950路)。
可見一般老城區,公交路數都不是很大~~~(認真想想,這不是顯而易見的的道理嘛)
4、8684網站上獲取青島市區公交線路
1、根據具體背景優化的代碼
遍歷一定範圍的數確實有其巧妙之處,但可能會遺漏一些特殊的專線公交,這時我們可以通過一些提供公交信息的網站,獲取具體區域、更詳細公交線路名信息:8684網青島市區線路
import requests
import json
import pandas as pd
import time
def get_line(cityname,line,path):
#獲取數據
url = 'https://restapi.amap.com/v3/bus/linename?s=rsv3&extensions=all&key=a5b7479db5b24fd68cedcf24f482c156&output=json&city={}&offset=1&keywords={}&platform=JS'.format(cityname,line)
r = requests.get(url).text
rt = json.loads(r)
try:
polyline=rt['buslines'][0]['polyline']
path=path+polyline
return path
except:
print('沒有{}公交'.format(line)) #正常情況下,這條語句不會執行
return path
if __name__=="__main__":
t0=time.time()
bus_name=[]
path_str=''
path={}
#讀取當前目錄下的公交線路.txt文檔,獲取公交線路名
with open("公交線路.txt", "r", encoding="utf-8") as f:
bus_name = f.readlines()
bus_name = bus_name[0].split(",")
for i in bus_name:
path_str=get_line('青島',i,path_str)
path['station_coords']=path_str.split(";")
path=pd.DataFrame(path)
path.to_csv('青島所有公交路線軌跡數據(8684).csv',index=False,encoding='utf-8')
print('8684網站上獲取青島市區公交線路:',len(bus_name),"條")
print("這些公交路徑座標數據有{}條".format(len(path['station_coords'])))
t1=time.time()
print("運行用時:%.2fs"%(t1-t0))
(2)運行結果
這樣的結果是錯誤的,很明顯是有個逗號爲中文逗號導致的!
修改後:
(3)補充代碼
和之前一樣,這樣的數據量高德地圖沒法一次讀入,需要分兩個表格保存後上傳。
path.iloc[0:49000, :].to_csv('青島所有公交路線軌跡數據(8684)-拆分數據1.csv',index=False,encoding='utf-8')
path.iloc[49000:, :].to_csv('青島所有公交路線軌跡數據(8684)-拆分數據2.csv',index=False,encoding='utf-8')
(4)可視化
這種規模的數據量搭配並不出色的電腦性能,不可避免的將創造的熱情減少了不少ㄟ( ▔, ▔ )ㄏa
青島市區所有公交線路軌跡圖: