<address id="zhpbl"></address>
<noframes id="zhpbl">
<address id="zhpbl"><form id="zhpbl"><th id="zhpbl"></th></form></address>

    <em id="zhpbl"></em>

      <address id="zhpbl"><th id="zhpbl"><progress id="zhpbl"></progress></th></address>
      更多精彩內容,歡迎關注:

      視頻號
      視頻號

      抖音
      抖音

      快手
      快手

      微博
      微博

      Python實現城市公交網絡分析與可視化

      文檔

      Python實現城市公交網絡分析與可視化

      這篇文章主要介紹了通過Python爬取城市公交站點、線路及其經緯度數據,并做可視化數據分析。文中的示例代碼講解詳細,感興趣的可以學習一下。
      推薦度:
      導讀這篇文章主要介紹了通過Python爬取城市公交站點、線路及其經緯度數據,并做可視化數據分析。文中的示例代碼講解詳細,感興趣的可以學習一下。
      一、數據查看和預處理

      數據獲取自高德地圖API,包含了天津市公交線路和站點名稱及其經緯度數據。

      import?pandas?as?pd
      
      df?=?pd.read_excel('site_information.xlsx')
      df.head()

      字段說明:

      線路名稱:公交線路的名稱

      上下行:0表示上行;1表示下行

      站序號:公交線路上行或下行依次經過站的序號

      站名稱:站點名稱

      經度(分):站點的經度

      緯度(分):站點的緯度

      數據字段少,結構也比較簡單,下面來充分了解我們的數據和進行預處理。

      總的數據有 30396 條,站名稱缺失了 5 條,緯度(分)缺失了 1 條,經度(分)缺失了 38 條,為了處理方便,直接把有缺失值的行刪除。

      經緯度數據是7031.982、2348.1016這樣的,需要將其轉換為以度為單位。

      df2?=?df1.copy()
      df2['經度(分)']?=?df1['經度(分)'].apply(float)?/?60
      df2['緯度(分)']?=?df1['緯度(分)'].apply(float)?/?60
      df2.head()

      處理后的數據里,共有 618 條公交線路,4851個站點數據。

      重新保存為處理后數據

      df2.to_excel("處理后數據.xlsx",?index=False)
      二、數據分析

      分析天津市公交站點的分布情況

      #?-*-?coding:?UTF-8?-*-
      """
      import?pandas?as?pd
      import?matplotlib.pyplot?as?plt
      import?matplotlib?as?mpl
      import?random
      
      df?=?pd.read_excel("處理后數據.xlsx")
      x_data?=?df['經度(分)']
      y_data?=?df['緯度(分)']
      colors?=?['#FF0000',?'#0000CD',?'#00BFFF',?'#008000',?'#FF1493',?'#FFD700',?'#FF4500',?'#00FA9A',?'#191970',?'#9932CC']
      colors?=?[random.choice(colors)?for?i?in?range(len(x_data))]
      mpl.rcParams['font.family']?=?'SimHei'
      plt.style.use('ggplot')
      #?設置大小
      plt.figure(figsize=(12,?6),?dpi=200)
      #?繪制散點圖??經度??緯度??傳進去???設置?顏色??點的大小
      plt.scatter(x_data,?y_data,?marker="o",?s=9.,?c=colors)
      
      #?添加描述信息?x軸?y軸?標題
      plt.xlabel("經度")
      plt.ylabel("緯度")
      plt.title("天津市公交站點分布情況")
      plt.savefig('經緯度散點圖.png')
      plt.show()

      結果如下:

      通過 matplotlib 繪制散點圖可視化天津市公交站點的分布情況,容易看出天津市的公交熱點分布區域。為了能更形象地分析公交線路網絡,我們可以將數據可視化在實際地圖上,利用 Pyecharts 的BMap。

      #?-*-?coding:?UTF-8?-*-
      """
      import?pandas?as?pd
      from?pyecharts.charts?import?BMap
      from?pyecharts?import?options?as?opts
      from?pyecharts.globals?import?CurrentConfig
      
      #?引用本地js資源渲染
      CurrentConfig.ONLINE_HOST?=?'D:/python/pyecharts-assets-master/assets/'
      
      df?=?pd.read_excel('處理后數據.xlsx',?encoding='utf-8')
      df.drop_duplicates(subset='站名稱',?inplace=True)
      longitude?=?list(df['經度(分)'])
      latitude?=?list(df['緯度(分)'])
      datas?=?[]
      a?=?[]
      for?i,?j?in?zip(longitude,?latitude):
      ????a.append([i,?j])
      
      datas.append(a)
      print(datas)
      
      BAIDU_MAP_AK?=?"改成你的百度地圖AK"
      
      c?=?(
      ????BMap(init_opts=opts.InitOpts(width="1200px",?height="800px"))
      ????.add_schema(
      ????????baidu_ak=BAIDU_MAP_AK,?????#?申請的BAIDU_MAP_AK
      ????????center=[117.20,?39.13],????#?天津市經緯度中心
      ????????zoom=10,
      ????????is_roam=True,
      ????)
      ????.add(
      ????????"",
      ????????type_="lines",
      ????????is_polyline=True,
      ????????data_pair=datas,
      ????????linestyle_opts=opts.LineStyleOpts(opacity=0.2,?width=0.5,?color='red'),
      ????????#?如果不是最新版本的話可以注釋下面的參數(效果差距不大)
      ????????progressive=200,
      ????????progressive_threshold=500,
      ????)
      )
      
      c.render('公交網絡地圖.html')

      結果如下:

      在地圖上可以看到,和平區、南開區公交線路網絡密集,交通便利。

      公交線路網絡中 i 節點代表第 i 條線路,其中節點 i 的度定義為與線路 i 可以經過換乘能夠到達的線路的數目,線路網絡的度大小反映了該條公交線路與其他線路的連通程度,構建算法分析公交線路網絡度的分布。

      #?-*-?coding:?UTF-8?-*-
      """
      import?xlrd
      import?matplotlib.pyplot?as?plt
      import?pandas?as?pd
      import?matplotlib?as?mpl
      
      
      df?=?pd.read_excel("site_information.xlsx")
      #?用pandas的操作去重???得到每條線路的名稱
      loc?=?df['線路名稱'].unique()
      #?得到每一條線路名稱的列表
      line_list?=?list(loc)
      print(line_list)
      
      #?打開Excel表格
      data?=?xlrd.open_workbook("site_information.xlsx")
      #?print(data)???#??在內存中
      #?獲取特定Sheet??索引為0??也就是第一個表
      table?=?data.sheets()[0]??#?從零開始
      #?每條線路對應有哪些站點??字典推導式
      site_dic?=?{k:?[]?for?k?in?line_list}
      site_list?=?[]
      for?i?in?range(1,?table.nrows):
      ????#?每一行的數據???返回的是一個列表
      ????x?=?table.row_values(i)
      ????if?x[1]?==?"0":
      ????????#?上行???站點數據??每條線路對應有哪些站點?添加進列表
      ????????site_dic[x[0]].append(x[3])
      ????????site_list.append(x[3])
      ????else:
      ????????continue
      #?print(len(site_dic))???#?618條線路
      #?print(len(site_list))??#?15248條站點數據
      print(f"公交網絡共有?{len(line_list)}?條線路")???#?618條線路
      
      #?先初始化一個統計每個節點的度的列表??與線路名稱列表里的索引一一對應
      node_count?=?[m?*?0?for?m?in?range(len(line_list))]
      #?以每條線路為一個節點??線路名稱為鍵??????值為一個列表??里面包含每條路線上行經過的所有站點
      sites?=?[site?for?site?in?site_dic.values()]
      #?print(sites)
      for?j?in?range(len(sites)):??#?類似冒泡法排序??比較多少趟
      ????for?k?in?range(j,?len(sites)?-?1):??#?每趟比較后??往后推一個??直到比較完??和防止越界
      ????????if?len(sites[j])?>?len(sites[k?+?1]):
      ????????????for?x?in?sites[j]:
      ????????????????if?x?in?sites[j]?and?x?in?sites[k?+?1]:???#?只要這兩條線路有公共站點??節點度數加1
      ????????????????????node_count[j],?node_count[k?+?1]?=?node_count[j]?+?1,?node_count[k?+?1]?+?1
      ????????????????????break???#?兩條線路對應在列表索引的值加1???這兩條線的比較結束
      ????????else:
      ????????????for?x?in?sites[k?+?1]:
      ????????????????if?x?in?sites[j]?and?x?in?sites[k?+?1]:???#?只要這兩條線路有公共站點??節點度數加1
      ????????????????????node_count[j],?node_count[k?+?1]?=?node_count[j]?+?1,?node_count[k?+?1]?+?1
      ????????????????????break???#?兩條線路對應在列表索引的值加1???這兩條線的比較結束
      #?print(node_count)
      #?節點編號?與?節點的度數索引對應
      node_number?=?[y?for?y?in?range(len(node_count))]
      #?線性網絡度的最大值???175
      print(f"線路網絡的度的最大值為:{max(node_count)}")
      print(f"線路網絡的度的最小值為:{min(node_count)}")
      print(f"線路網絡的度的平均值為:{sum(node_count)?/?len(node_count)}")
      #?設置大小??圖的像素
      #?設置字體???matplotlib?不支持顯示中文??自己本地設置
      plt.figure(figsize=(10,?6),?dpi=150)
      mpl.rcParams['font.family']?=?'SimHei'
      
      #?繪制每個節點度的分布
      plt.bar(node_number,?node_count,?color="purple")
      
      #?添加描述信息
      plt.xlabel("節點編號n")
      plt.ylabel("節點的度數K")
      plt.title("線路網絡中各節點的度的大小分布",?fontsize=15)
      plt.savefig("線路網絡中各節點的度的大小.png")
      plt.show()

      結果如下:

      公交網絡共有 618 條線路

      線路網絡的度的最大值為:175

      線路網絡的度的最小值為:0

      線路網絡的度的平均值為:55.41423948220065

      import?xlrd
      import?matplotlib.pyplot?as?plt
      import?pandas?as?pd
      import?matplotlib?as?mpl
      import?collections
      
      df?=?pd.read_excel("site_information.xlsx")
      #?用pandas的操作去重???得到每條線路的名稱
      loc?=?df['線路名稱'].unique()
      #?得到每一條線路名稱的列表
      line_list?=?list(loc)
      print(line_list)
      
      #?打開Excel表格
      data?=?xlrd.open_workbook("site_information.xlsx")
      #?print(data)???#??在內存中
      #?獲取特定Sheet??索引為0??也就是第一個表
      table?=?data.sheets()[0]??#?從零開始
      #?每條線路對應有哪些站點??字典推導式
      site_dic?=?{k:?[]?for?k?in?line_list}
      site_list?=?[]
      for?i?in?range(1,?table.nrows):
      ????#?每一行的數據???返回的是一個列表
      ????x?=?table.row_values(i)
      ????if?x[1]?==?"0":
      ????????#?上行???站點數據??每條線路對應有哪些站點?添加進列表
      ????????site_dic[x[0]].append(x[3])
      ????????site_list.append(x[3])
      ????else:
      ????????continue
      #?print(len(site_dic))???#?618條線路
      #?print(len(site_list))??#?15248條站點數據
      #?先初始化一個統計每個節點的度的列表??與線路名稱列表里的索引一一對應
      node_count?=?[m?*?0?for?m?in?range(len(line_list))]
      #?以每條線路為一個節點??線路名稱為鍵??????值為一個列表??里面包含每條路線上行經過的所有站點
      sites?=?[site?for?site?in?site_dic.values()]
      #?print(sites)
      for?j?in?range(len(sites)):??#?類似冒泡法排序??比較多少趟
      ????for?k?in?range(j,?len(sites)?-?1):??#?每趟比較后??往后推一個??直到比較完??和防止越界
      ????????if?len(sites[j])?>?len(sites[k?+?1]):
      ????????????for?x?in?sites[j]:
      ????????????????if?x?in?sites[j]?and?x?in?sites[k?+?1]:???#?只要這兩條線路有公共站點??節點度數加1
      ????????????????????node_count[j],?node_count[k?+?1]?=?node_count[j]?+?1,?node_count[k?+?1]?+?1
      ????????????????????break???#?兩條線路對應在列表索引的值加1???這兩條線的比較結束
      ????????else:
      ????????????for?x?in?sites[k?+?1]:
      ????????????????if?x?in?sites[j]?and?x?in?sites[k?+?1]:???#?只要這兩條線路有公共站點??節點度數加1
      ????????????????????node_count[j],?node_count[k?+?1]?=?node_count[j]?+?1,?node_count[k?+?1]?+?1
      ????????????????????break???#?兩條線路對應在列表索引的值加1???這兩條線的比較結束
      #?print(node_count)
      #?節點編號?與?節點的度數索引對應
      node_number?=?[y?for?y?in?range(len(node_count))]
      #?線性網絡度的最大值???175
      #?print(max(node_count))
      
      #?設置大小??圖的像素
      #?設置字體???matplotlib?不支持顯示中文??自己本地設置
      plt.figure(figsize=(10,?6),?dpi=150)
      mpl.rcParams['font.family']?=?'SimHei'
      
      #?分析節點的度K的概率分布
      #?統計節點的度為K的?分別有多少個
      node_count?=?collections.Counter(node_count)
      node_count?=?node_count.most_common()
      #?點
      node_dic?=?{_k:?_v?for?_k,?_v?in?node_count}
      #?按鍵從小到大排序???得到一個列表??節點的度
      sort_node?=?sorted(node_dic)
      #?按順序得到鍵對應的值???即有相同節點的度的個數
      sort_num?=?[node_dic[q]?for?q?in?sort_node]
      #?概率分布中度平均值??總的度數加起來??/?個數
      #?print(sum(sort_node)/len(sort_node))
      #?概率分布中最大的度值???也就個數最多那個
      print(f"概率分布中概率最大的度值為:{max(sort_num)}")
      
      probability?=?[s1?/?sum(sort_num)?for?s1?in?sort_num]???#?概率分布
      print(probability)
      
      #?天津市公交線路節點概率分布圖像
      plt.bar(sort_node,?probability,?color="red")
      #?添加描述信息
      plt.xlabel("節點的度K")
      plt.ylabel("節點度為K的概率P(K)")
      plt.title("線路網絡中節點度的概率分布",?fontsize=15)
      
      plt.savefig("線路網絡中節點度的概率分布.png")
      plt.show()

      結果如下:

      概率分布中概率最大的度值為:16

      天津市公交線路網絡的度分布如上圖所示,本文收集的天津市線路網絡共有 618 條線路組成,線路網絡的度的最大值為175。概率分布中概率最大的度值為16,度平均值為55.41,表明天津市公交網絡提供的換乘機會較多,使得可達性較高。其中概率較大的度值大多集中在 7~26 之間。使得節點強度分布相對來說不夠均勻,造成天津市很多路段公交線路較少,少數路段經過線路過于密集,造成資源的浪費。

      聚類系數是研究節點鄰居之間的連接緊密程度,因此不必考慮邊的方向。對于有向圖,將其當成無向圖來處理。網絡聚類系數大,表明網絡中節點與其附近節點之間的連接緊密度程度高,即與實際站點之間的公交線路連接密集。計算得到天津公交復雜網絡的聚類系數為0.091,相對其他城市較低。

      根據公式:

      同規模的隨機網絡聚集系數約為0.00044,進一步體現了網絡的小世界特性。

      import?xlrd
      import?matplotlib.pyplot?as?plt
      import?pandas?as?pd
      import?matplotlib?as?mpl
      
      
      #?讀取數據
      df?=?pd.read_excel("site_information.xlsx")
      #?用pandas的操作去重???得到每條線路的名稱
      loc?=?df['線路名稱'].drop_duplicates()
      #?得到每一條線路名稱的列表??按照Excel表里以次下去的順序
      line_list?=?list(loc)
      #?print(line_list)
      
      #?打開Excel表格
      data?=?xlrd.open_workbook("site_information.xlsx")
      #?print(data)???#??在內存中
      #?獲取特定Sheet??索引為0??也就是第一個表
      table?=?data.sheets()[0]??#?從零開始
      #?每條線路對應有哪些站點??字典推導式
      site_dic?=?{k:?[]?for?k?in?line_list}
      site_list?=?[]
      for?i?in?range(1,?table.nrows):
      ????#?每一行的數據???返回的是一個列表
      ????x?=?table.row_values(i)
      ????if?x[1]?==?"0":
      ????????#?只取上行站點數據??每條線路對應有哪些站點?添加進列表
      ????????site_dic[x[0]].append(x[3])
      ????????site_list.append(x[3])
      ????else:
      ????????continue
      #?print(len(site_dic))???#?618條線路
      #?print(len(site_list))??#?15248條站點數據
      #?先初始化一個統計每個節點的度的列表??與線路名稱列表里的索引一一對應
      node_count?=?[m?*?0?for?m?in?range(len(line_list))]
      #?以每條線路為一個節點??線路名稱為鍵??????值為一個列表??里面包含每條路線上行經過的所有站點
      sites?=?[site?for?site?in?site_dic.values()]
      #?print(sites)
      #?統計各節點的度
      for?j?in?range(len(sites)?-?1):??#?類似冒泡法排序??比較多少趟
      ????for?k?in?range(j,?len(sites)?-?1):??#?每趟比較后??往后推一個??直到比較完??和防止越界
      ????????if?len(sites[j])?>?len(sites[k?+?1]):
      ????????????for?x?in?sites[j]:
      ????????????????if?x?in?sites[j]?and?x?in?sites[k?+?1]:???#?只要這兩條線路有公共站點??節點度數加1
      ????????????????????node_count[j],?node_count[k?+?1]?=?node_count[j]?+?1,?node_count[k?+?1]?+?1
      ????????????????????break???#?兩條線路對應在列表索引的值加1???這兩條線的比較結束
      ????????else:
      ????????????for?x?in?sites[k?+?1]:
      ????????????????if?x?in?sites[j]?and?x?in?sites[k?+?1]:???#?只要這兩條線路有公共站點??節點度數加1
      ????????????????????node_count[j],?node_count[k?+?1]?=?node_count[j]?+?1,?node_count[k?+?1]?+?1
      ????????????????????break???#?兩條線路對應在列表索引的值加1???這兩條線的比較結束
      
      #?找到該節點的鄰居節點??鄰居節點間實際的邊數
      Ei?=?[]
      #?對每條線路進行找鄰接節點??并統計其鄰接節點點實際的邊數
      for?a?in?range(len(sites)):
      ????neighbor?=?[]
      ????if?node_count[a]?==?0:
      ????????Ei.append(0)
      ????????continue
      ????if?node_count[a]?==?1:
      ????????Ei.append(0)
      ????????continue
      ????for?b?in?range(len(sites)):
      ????????if?a?==?b:????#?自身??不比
      ????????????continue
      ????????if?len(sites[a])?>?len(sites[b]):???#?從站點多的線路里選取站點???看是否有公共站點
      ????????????for?x?in?sites[a]:
      ????????????????if?x?in?sites[a]?and?x?in?sites[b]:??#?找到鄰居節點
      ????????????????????neighbor.append(sites[b])
      ????????????????????break
      ????????else:
      ????????????for?x?in?sites[b]:
      ????????????????if?x?in?sites[a]?and?x?in?sites[b]:??#?找到鄰居節點
      ????????????????????neighbor.append(sites[b])
      ????????????????????break
      ????#?在鄰居節點中判斷這些節點的實際邊數??又類似前面的方法??判斷兩兩是否相連
      ????count?=?0
      ????for?c?in?range(len(neighbor)?-?1):
      ????????for?d?in?range(c,?len(neighbor)?-?1):??#?每趟比較后??往后推一個??直到比較完??和防止越界
      ????????????try:
      ????????????????if?len(sites[c])?>?len(sites[d?+?1]):
      ????????????????????for?y?in?sites[c]:
      ????????????????????????if?y?in?sites[c]?and?y?in?sites[d?+?1]:??#?鄰居節點這兩個也相連
      ????????????????????????????count?+=?1
      ????????????????????????????break
      ????????????????????????else:
      ????????????????????????????continue
      ????????????????else:
      ????????????????????for?y?in?sites[d?+?1]:
      ????????????????????????if?y?in?sites[c]?and?y?in?sites[d?+?1]:??#?鄰居節點這兩個也相連
      ????????????????????????????count?+=?1
      ????????????????????????????break
      ????????????????????????else:
      ????????????????????????????continue
      ????????????except?IndexError:
      ????????????????break
      ????Ei.append(count)
      
      #?每個節點的鄰居節點間實際相連的邊數
      #?print(Ei)
      #?節點編號?與?節點的度數索引對應
      node_number?=?[y?for?y?in?range(len(node_count))]
      
      #?設置字體???matplotlib?不支持顯示中文??自己本地設置
      mpl.rcParams['font.family']?=?'SimHei'
      #?設置大小??圖的像素
      plt.figure(figsize=(10,?6),?dpi=150)
      #?公交線路網絡的聚類系數分布圖像???相鄰節點的連通程度
      Ci?=?[]
      for?m?in?range(len(node_number)):
      ????if?node_count[m]?==?0:
      ????????Ci.append(0)
      ????elif?node_count[m]?==?1:
      ????????Ci.append(0)
      
      ????else:??#?2?*?該節點鄰居節點實際連接邊數?/?最大邊數
      ????????Ci.append(2?*?Ei[m]?/?(node_count[m]?*?(node_count[m]?-?1)))
      
      #?各節點鄰居節點的連通程度?計算平均聚類系數
      print("天津市公交線路網絡平均聚類系數為:{:.4f}".format(sum(Ci)?/?len(Ci)))
      plt.bar(node_number,?Ci,?color="blue")
      
      #?添加描述信息
      plt.xlabel("節點編號n")
      plt.ylabel("節點的聚類系數")
      plt.title("線路網絡中各節點的聚類系數分布",?fontsize=15)
      
      plt.savefig("聚類系數分布.png")
      plt.show()

      結果如下:

      天津市公交線路網絡平均聚類系數為:0.0906

      文檔

      Python實現城市公交網絡分析與可視化

      這篇文章主要介紹了通過Python爬取城市公交站點、線路及其經緯度數據,并做可視化數據分析。文中的示例代碼講解詳細,感興趣的可以學習一下。
      推薦度:
      為你推薦
      資訊專欄
      熱門視頻
      相關推薦
      Python數據分析處理(三)--運動員信息的分組與聚合 基于Python實現PDF區域文本提取工具 詳解python的循環 python實現新年倒計時實例代碼 Python實現消消樂小游戲 分享15個超級好用得Python實用技巧 學習python的while循環嵌套 提升Python運行速度的5個小技巧 Python按鍵或值對字典進行排序 圖像檢索之基于vlfeat實現SIFT特征 python繪圖中的四個繪圖技巧 js中toString方法3個作用 描寫春天花朵的詩句 關于思念的詩句 帶馬字的詩句 牡丹花的詩句 想念的詩句 含雁的詩句 愁的詩句 珍惜時間的名言 Python&nbsp;垃圾回收機制詳解 關于樹的詩句 緬懷親人的詩句 春暖花開的詩句 家國情懷的詩句 含有星字的詩句 用來贊美老師的詩句 看破紅塵的經典詩句 長江的詩句 關于傳統節日的詩句 三月桃花的詩句 夕陽的詩句 紀念烈士的詩句 西湖的詩句 贊美虎的詩句 與蓮有關的詩句 梅蘭竹菊的詩句 描寫山的詩句有哪些 描寫植物的詩句 傳統節日的詩句
      Top 少妇高潮太爽了在线视频