歡迎光臨
每天分享高質量文章

183條地鐵線路,3034個地鐵站,發現中國城市地名的秘密

導讀:最近看了新周刊的一篇推送《我們分析了3447個地鐵站,發現了中國城市地名的秘密》,有關地鐵名字的分析。

於是乎也想著自己去獲取資料,然後進行分析一番。

分析水平或許不能和他們的相比,但提高資料的準確性那篇文章中所用到的地鐵站資料並沒有去重,對於換乘站,含有大量重覆。即使作者一直在強調換乘站占比很小,影響不是很大。

但於我而言,去除重覆資料還是比較簡單的。

然後照著人家的路子去分析,學習一下思路。

 

 

作者:小F

來源:法納斯特(ID:walker398)

01 獲取分析

地鐵信息獲取從高德地圖上獲取。

上面主要獲取城市的「id」「cityname」及「名稱」。

用於拼接請求網址,進而獲取地鐵線路的具體信息。

找到請求信息,獲取各個城市的地鐵線路以及線路中站點詳情。

02 資料獲取

具體代碼如下。

import json
import requests
from bs4 import BeautifulSoup

essay-headers = {'user-agent''Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}


def get_message(ID, cityname, name):
    """
    地鐵線路信息獲取
    """
    url = 'http://map.amap.com/service/subway?_1555502190153&srhdata;=' + ID + '_drw_' + cityname + '.json'
    response = requests.get(url=url, essay-headers=essay-headers)
    html = response.text
    result = json.loads(html)
    for i in result['l']:
        for j in i['st']:
            # 判斷是否含有地鐵分線
            if len(i['la']) > 0:
                print(name, i['ln'] + '(' + i['la'] + ')', j['n'])
                with open('subway.csv''a+', encoding='gbk'as f:
                    f.write(name + ',' + i['ln'] + '(' + i['la'] + ')' + ',' + j['n'] + '\n')
            else:
                print(name, i['ln'], j['n'])
                with open('subway.csv''a+', encoding='gbk'as f:
                    f.write(name + ',' + i['ln'] + ',' + j['n'] + '\n')


def get_city():
    """
    城市信息獲取
    """
    url = 'http://map.amap.com/subway/index.html?&1100'
    response = requests.get(url=url, essay-headers=essay-headers)
    html = response.text
    # 編碼
    html = html.encode('ISO-8859-1')
    html = html.decode('utf-8')
    soup = BeautifulSoup(html, 'lxml')
    # 城市串列
    res1 = soup.find_all(class_="city-list fl")[0]
    res2 = soup.find_all(class_="more-city-list")[0]
    for i in res1.find_all('a'):
        # 城市ID值
        ID = i['id']
        # 城市拼音名
        cityname = i['cityname']
        # 城市名
        name = i.get_text()
        get_message(ID, cityname, name)
    for i in res2.find_all('a'):
        # 城市ID值
        ID = i['id']
        # 城市拼音名
        cityname = i['cityname']
        # 城市名
        name = i.get_text()
        get_message(ID, cityname, name)


if __name__ == '__main__':
    get_city()

最後成功獲取資料。

包含換乘站資料,一共3541個地鐵站點。

03 資料可視化

先對資料進行清洗,去除重覆的換乘站信息。

from wordcloud import WordCloud, ImageColorGenerator
from pyecharts import Line, Bar
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import jieba

# 設置列名與資料對齊
pd.set_option('display.unicode.ambiguous_as_wide'True)
pd.set_option('display.unicode.east_asian_width'True)
# 顯示10行
pd.set_option('display.max_rows'10)
# 讀取資料
df = pd.read_csv('subway.csv', essay-header=None, names=['city''line''station'], encoding='gbk')
# 各個城市地鐵線路情況
df_line = df.groupby(['city''line']).count().reset_index()
print(df_line)

通過城市及地鐵線路進行分組,得到全國地鐵線路總數。

一共183條地鐵線路。

def create_map(df):
    # 繪製地圖
    value = [i for i in df['line']]
    attr = [i for i in df['city']]
    geo = Geo("已開通地鐵城市分佈情況", title_pos='center', title_top='0', width=800, height=400, title_color="#fff", background_color="#404a59", )
    geo.add("", attr, value, is_visualmap=True, visual_range=[025], visual_text_color="#fff", symbol_size=15)
    geo.render("已開通地鐵城市分佈情況.html")


def create_line(df):
    """
    生成城市地鐵線路數量分佈情況
    """
    title_len = df['line']
    bins = [0510152025]
    level = ['0-5''5-10''10-15''15-20''20以上']
    len_stage = pd.cut(title_len, bins=bins, labels=level).value_counts().sort_index()
    # 生成柱狀圖
    attr = len_stage.index
    v1 = len_stage.values
    bar = Bar("各城市地鐵線路數量分佈", title_pos='center', title_top='18', width=800, height=400)
    bar.add("", attr, v1, is_stack=True, is_label_show=True)
    bar.render("各城市地鐵線路數量分佈.html")


# 各個城市地鐵線路數
df_city = df_line.groupby(['city']).count().reset_index().sort_values(by='line', ascending=False)
print(df_city)
create_map(df_city)
create_line(df_city)

已經開通地鐵的城市資料,還有各個城市的地鐵線路數。

一共32個城市開通地鐵,大部分都是省會城市,還有個別經濟實力強的城市。其中北京、上海線路已經超過了20條。

線路數量分佈情況。

可以看到大部分還是在「0-5」這個階段的,當然最少為1條線。

# 哪個城市哪條線路地鐵站最多
print(df_line.sort_values(by='station', ascending=False))

探索一下哪個城市哪條線路地鐵站最多。

北京10號線第一,重慶3號線第二。

還是蠻懷念北京1張票,2塊錢地鐵隨便做的時候。

可惜好日子一去不復返了。

去除重覆換乘站資料。

# 去除重覆換乘站的地鐵資料
df_station = df.groupby(['city''station']).count().reset_index()
print(df_station)

一共包含3034個地鐵站,相較新周刊中3447個地鐵站資料,減少了近400個地鐵站。

接下來看一下哪個城市地鐵站最多。

# 統計每個城市包含地鐵站數(已去除重覆換乘站)
print(df_station.groupby(['city']).count().reset_index().sort_values(by='station', ascending=False))

32個城市,上海第一,北京第二。沒想到的是,武漢居然有那麼多地鐵站。

 

現在來實現一下新周刊中的操作,生成地鐵名詞雲。

def create_wordcloud(df):
    """
    生成地鐵名詞雲
    """
    # 分詞
    text = ''
    for line in df['station']:
        text += ' '.join(jieba.cut(line, cut_all=False))
        text += ' '
    backgroud_Image = plt.imread('rocket.jpg')
    wc = WordCloud(
        background_color='white',
        mask=backgroud_Image,
        font_path='C:\Windows\Fonts\華康儷金黑W8.TTF',
        max_words=1000,
        max_font_size=150,
        min_font_size=15,
        prefer_horizontal=1,
        random_state=50,
    )
    wc.generate_from_text(text)
    img_colors = ImageColorGenerator(backgroud_Image)
    wc.recolor(color_func=img_colors)
    # 看看詞頻高的有哪些
    process_word = WordCloud.process_text(wc, text)
    sort = sorted(process_word.items(), key=lambda e: e[1], reverse=True)
    print(sort[:50])
    plt.imshow(wc)
    plt.axis('off')
    wc.to_file("地鐵名詞雲.jpg")
    print('生成詞雲成功!')


create_wordcloud(df_station)

詞雲圖如下。

廣場、大道、公園占了前三,和新周刊的圖片一樣,說明分析有效。

words = []
for line in df['station']:
    for i in line:
        # 將字串輸出一個個中文
        words.append(i)


def all_np(arr):
    """
    統計單字頻率
    """
    arr = np.array(arr)
    key = np.unique(arr)
    result = {}
    for k in key:
        mask = (arr == k)
        arr_new = arr[mask]
        v = arr_new.size
        result[k] = v
    return result


def create_word(word_message):
    """
    生成柱狀圖
    """
    attr = [j[0for j in word_message]
    v1 = [j[1for j in word_message]
    bar = Bar("中國地鐵站最愛用的字", title_pos='center', title_top='18', width=800, height=400)
    bar.add("", attr, v1, is_stack=True, is_label_show=True)
    bar.render("中國地鐵站最愛用的字.html")


word = all_np(words)
word_message = sorted(word.items(), key=lambda x: x[1], reverse=True)[:10]
create_word(word_message)

統計一下,大家最喜歡用什麼字來命名地鐵。

最多,其中上海的占比很大。

不信往下看。

# 選取上海的地鐵站
df1 = df_station[df_station['city'] == '上海']
print(df1)

統計上海所有的地鐵站,一共345個。

選取包含的地鐵站。

# 選取上海地鐵站名字包含路的資料
df2 = df1[df1['station'].str.contains('路')]
print(df2)

有210個,約占上海地鐵的三分之二,的七分之二。

看來上海對是情有獨鐘的。

具體緣由這裡就不解釋了,詳情見新周刊的推送,裡面還是講解蠻詳細的。

武漢和重慶則是對這個詞特別喜歡。標志著那片土地開拓者們的籍貫與姓氏。

# 選取武漢的地鐵站
df1 = df_station[df_station['city'] == '武漢']
print(df1)
# 選取武漢地鐵站名字包含家的資料
df2 = df1[df1['station'].str.contains('家')]
print(df2)

# 選取重慶的地鐵站
df1 = df_station[df_station['city'] == '重慶']
print(df1)
# 選取重慶地鐵站名字包含家的資料
df2 = df1[df1['station'].str.contains('家')]
print(df2)

武漢共有17個,重慶共有20個。

看完家之後,再來看一下名字包含的地鐵站。

def create_door(door):
    """
    生成柱狀圖
    """
    attr = [j for j in door['city'][:3]]
    v1 = [j for j in door['line'][:3]]
    bar = Bar("地鐵站最愛用“門”命名的城市", title_pos='center', title_top='18', width=800, height=400)
    bar.add("", attr, v1, is_stack=True, is_label_show=True, yaxis_max=40)
    bar.render("地鐵站最愛用門命名的城市.html")


# 選取地鐵站名字包含門的資料
df1 = df_station[df_station['station'].str.contains('門')]
# 對資料進行分組計數
df2 = df1.groupby(['city']).count().reset_index().sort_values(by='line', ascending=False)
print(df2)
create_door(df2)

一共有21個城市,地鐵站名包含

其中北京,南京,西安作為多朝古都,占去了大部分。

具體的地鐵站名資料。

# 選取北京的地鐵站
df1 = df_station[df_station['city'] == '北京']
# 選取北京地鐵站名字包含門的資料
df2 = df1[df1['station'].str.contains('門')]
print(df2)

# 選取南京的地鐵站
df1 = df_station[df_station['city'] == '南京']
# 選取南京地鐵站名字包含門的資料
df2 = df1[df1['station'].str.contains('門')]
print(df2)

# 選取西安的地鐵站
df1 = df_station[df_station['city'] == '西安']
# 選取西安地鐵站名字包含門的資料
df2 = df1[df1['station'].str.contains('門')]
print(df2)

輸出如下。

04 總結

原始碼及相關檔案已上傳GitHub,鏈接:

 

https://github.com/Tobby-star/subway_analysis

這裡摘一段新周刊的話。

可以說,一個小小的地鐵名就是一座城市風貌的一部分。它反映著不同地方的水土,也承載著各個城市的文化和歷史。

 

確實如此,靠山的城市地鐵名多“山”,靠水的城市地鐵名“含水量”則是杠杠的。

    已同步到看一看
    赞(0)

    分享創造快樂