手把手教你完成一個資料科學小專案(6):城市提取與視覺化

古柳_Deserts_X發表於2018-08-20

前言

請先閱讀《“中國年輕人正帶領國家走向危機”,這鍋背是不背? 》 一文,以對“手把手教你完成一個資料科學小專案”系列有個全域性性的瞭解。

程式碼統一開源在 GitHub:DesertsX/gulius-projects ,感興趣的朋友可以先行 star 哈。歡迎關注公眾號“牛衣古柳”(ID:Deserts-X),以及喜歡Python的朋友,歡迎加Python交友娛樂會所(QQ群:613176398),娛樂會所,沒有嫩模。本系列程式碼有疑惑的可前來詢問哈!

截至目前我們已經完成了資料爬取資料提取與IP查詢資料異常與清洗評論數變化情況分析省份提取與視覺化,本文將提取城市資料,並用 pyecharts 完成地圖視覺化。

手把手教你完成一個資料科學小專案(6):城市提取與視覺化

讀取資料

前面幾步都在上一篇文章裡講過了,因為牽扯許多相關的操作,所以很快的過一遍。

import pandas as pd
df = pd.read_csv('Sina_Finance_Comments_All_20180811_Cleaned.csv',encoding='utf-8')
df[['area','ip_loc']]
複製程式碼

統計 area

看看area列有多少種情況。

area_count = df.groupby('area')['area'].count().sort_values(ascending=False)
area_name = list(area_count.index)
area_values = area_count.values
print(len(area_name),len(area_values))
print(area_count)
複製程式碼

資料處理思路

首先再次明確下這次的目的是提取出省份和城市資訊,且由於資料量不大,所以後續只在中國地圖上進行視覺化,因而海外地理資訊統一可以篩選出去,實現的方式是按照國家名手動構建一個unchina的列表,用來儲存本次資料裡出現的海外國家,然後遍歷所有的337條area_name元素,包含這些國家名的就新增到drop列表裡,然後根據其他國內的地理資訊的長度分別列印出來,這樣資料就清晰多了!過程中可能有些會被誤分,需要核查一遍。

area_len_2 = []
area_len_3 = []
area_len_4 = []
area_len_5 = []
unchina = ['英國','美國','日本','瑞士','法國','瑞典','越南','泰國',
           '義大利','加拿大','菲律賓','新加坡','紐西蘭','伊拉克','愛爾蘭','安哥拉',
           '澳大利亞', '大韓民國', '馬來西亞']
droped = []
for area in area_name:
    for unarea in unchina:
        if unarea in area: 
            droped.append(area)
    if len(area)==2 and area not in droped: area_len_2.append(area) # 我國共有34個省級行政區域,包括23個省,5個自治區,4個直轄市,2個特別行政區。
    if len(area)==3 and area not in droped: area_len_3.append(area)
    if len(area)==4 and area not in droped: area_len_4.append(area)
    if len(area)>=5 and area not in droped: area_len_5.append(area)
print(len(droped),'\n', droped)
print(len(area_len_2),'\n', area_len_2)
print(len(area_len_3),'\n', area_len_3)
print(len(area_len_4),'\n', area_len_4)
print(len(area_len_5),'\n', area_len_5)
複製程式碼

省份彙總

根據百度百科詞條裡的內容:省份 - 百科我國共有34個省級行政區域,包括23個省,5個自治區,4個直轄市,2個特別行政區。

複製過來所有省份,先手動去掉自治區和行政區的字尾文字,再用程式碼去掉無關的文字與字元。

prolist = '北京市,天津市,上海市,重慶市,河北省,山西省,遼寧省,吉林省,江蘇省,浙江省,安徽省,福建省,\
江西省,山東省,河南省,湖北省,湖南省,廣東省,海南省,四川省,貴州省,雲南省,陝西省,甘肅省,\
青海省,臺灣省,廣西,西藏,寧夏,新疆,香港,澳門,內蒙古,黑龍江省'
prolist = prolist.replace('市', '').replace('省', '').split(',')
print(len(prolist), prolist)
複製程式碼

34個省份

['北京', '天津', '上海', '重慶', '河北', '山西', '遼寧', '吉林', '江蘇', '浙江', '安徽', '福建', '江西', '山東', '河南', '湖北', '湖南', '廣東', '海南', '四川', '貴州', '雲南', '陝西', '甘肅', '青海', '臺灣', '廣西', '西藏', '寧夏', '新疆', '香港', '澳門', '內蒙古', '黑龍江']
複製程式碼

城市提取

上面相關程式碼過一遍後,接下來就是本文的重點,提取城市資料並進行視覺化了。

根據以前的經驗可知,個別點的經緯度資料可能沒有內建,所以呼叫地圖時,會無法顯示並報錯。所以先要確定哪些資料可用,哪些不可用,但到底 ECharts 或 pyecharts 裡內建了哪些資料目前還沒了解過。望知曉的朋友可以告知。

本次採取的方式是:從 ECharts 官網的effectScatter-bmap示例中提取出城市列表,便於篩選。當然事先並不知道這裡的資料和本次評論的資料的匹配度多高,只能“實踐出真知”。

geoCoordMap = {'海門':[121.15,31.89],'鄂爾多斯':[109.781327,39.608266],'招遠':[120.38,37.35],'舟山':[122.207216,29.985295],'齊齊哈爾':[123.97,47.33],'鹽城':[120.13,33.38],'赤峰':[118.87,42.28],'青島':[120.33,36.07],'乳山':[121.52,36.89],'金昌':[102.188043,38.520089],'泉州':[118.58,24.93],'萊西':[120.53,36.86],'日照':[119.46,35.42],'膠南':[119.97,35.88],'南通':[121.05,32.08],'拉薩':[91.11,29.97],'雲浮':[112.02,22.93],'梅州':[116.1,24.55],'文登':[122.05,37.2],'上海':[121.48,31.22],'攀枝花':[101.718637,26.582347],'威海':[122.1,37.5],'承德':[117.93,40.97],'廈門':[118.1,24.46],'汕尾':[115.375279,22.786211],'潮州':[116.63,23.68],'丹東':[124.37,40.13],'太倉':[121.1,31.45],'曲靖':[103.79,25.51],'煙臺':[121.39,37.52],'福州':[119.3,26.08],'瓦房店':[121.979603,39.627114],'即墨':[120.45,36.38],'撫順':[123.97,41.97],'玉溪':[102.52,24.35],'張家口':[114.87,40.82],'陽泉':[113.57,37.85],'萊州':[119.942327,37.177017],'湖州':[120.1,30.86],'汕頭':[116.69,23.39],'崑山':[120.95,31.39],'寧波':[121.56,29.86],'湛江':[110.359377,21.270708],'揭陽':[116.35,23.55],'榮成':[122.41,37.16],'連雲港':[119.16,34.59],'葫蘆島':[120.836932,40.711052],'常熟':[120.74,31.64],'東莞':[113.75,23.04],'河源':[114.68,23.73],'淮安':[119.15,33.5],'泰州':[119.9,32.49],'南寧':[108.33,22.84],'營口':[122.18,40.65],'惠州':[114.4,23.09],'江陰':[120.26,31.91],'蓬萊':[120.75,37.8],'韶關':[113.62,24.84],'嘉峪關':[98.289152,39.77313],'廣州':[113.23,23.16],'延安':[109.47,36.6],'太原':[112.53,37.87],'清遠':[113.01,23.7],'中山':[113.38,22.52],'昆明':[102.73,25.04],'壽光':[118.73,36.86],'盤錦':[122.070714,41.119997],'長治':[113.08,36.18],'深圳':[114.07,22.62],'珠海':[113.52,22.3],'宿遷':[118.3,33.96],'咸陽':[108.72,34.36],'銅川':[109.11,35.09],'平度':[119.97,36.77],'佛山':[113.11,23.05],'海口':[110.35,20.02],'江門':[113.06,22.61],'章丘':[117.53,36.72],'肇慶':[112.44,23.05],'大連':[121.62,38.92],'臨汾':[111.5,36.08],'吳江':[120.63,31.16],'石嘴山':[106.39,39.04],'瀋陽':[123.38,41.8],'蘇州':[120.62,31.32],'茂名':[110.88,21.68],'嘉興':[120.76,30.77],'長春':[125.35,43.88],'膠州':[120.03336,36.264622],'銀川':[106.27,38.47],'張家港':[120.555821,31.875428],'三門峽':[111.19,34.76],'錦州':[121.15,41.13],'南昌':[115.89,28.68],'柳州':[109.4,24.33],'三亞':[109.511909,18.252847],'自貢':[104.778442,29.33903],'吉林':[126.57,43.87],'陽江':[111.95,21.85],'瀘州':[105.39,28.91],'西寧':[101.74,36.56],'宜賓':[104.56,29.77],'呼和浩特':[111.65,40.82],'成都':[104.06,30.67],'大同':[113.3,40.12],'鎮江':[119.44,32.2],'桂林':[110.28,25.29],'張家界':[110.479191,29.117096],'宜興':[119.82,31.36],'北海':[109.12,21.49],'西安':[108.95,34.27],'金壇':[119.56,31.74],'東營':[118.49,37.46],'牡丹江':[129.58,44.6],'遵義':[106.9,27.7],'紹興':[120.58,30.01],'揚州':[119.42,32.39],'常州':[119.95,31.79],'濰坊':[119.1,36.62],'重慶':[106.54,29.59],'台州':[121.420757,28.656386],'南京':[118.78,32.04],'濱州':[118.03,37.36],'貴陽':[106.71,26.57],'無錫':[120.29,31.59],'本溪':[123.73,41.3],'克拉瑪依':[84.77,45.59],'渭南':[109.5,34.52],'馬鞍山':[118.48,31.56],'寶雞':[107.15,34.38],'焦作':[113.21,35.24],'句容':[119.16,31.95],'北京':[116.46,39.92],'徐州':[117.2,34.26],'衡水':[115.72,37.72],'包頭':[110,40.58],'綿陽':[104.73,31.48],'烏魯木齊':[87.68,43.77],'棗莊':[117.57,34.86],'杭州':[120.19,30.26],'淄博':[118.05,36.78],'鞍山':[122.85,41.12],'溧陽':[119.48,31.43],'庫爾勒':[86.06,41.68],'安陽':[114.35,36.1],'開封':[114.35,34.79],'濟南':[117,36.65],'德陽':[104.37,31.13],'溫州':[120.65,28.01],'九江':[115.97,29.71],'邯鄲':[114.47,36.6],'臨安':[119.72,30.23],'蘭州':[103.73,36.03],'滄州':[116.83,38.33],'臨沂':[118.35,35.05],'南充':[106.110698,30.837793],'天津':[117.2,39.13],'富陽':[119.95,30.07],'泰安':[117.13,36.18],'諸暨':[120.23,29.71],'鄭州':[113.65,34.76],'哈爾濱':[126.63,45.75],'聊城':[115.97,36.45],'蕪湖':[118.38,31.33],'唐山':[118.02,39.63],'平頂山':[113.29,33.75],'邢臺':[114.48,37.05],'德州':[116.29,37.45],'濟寧':[116.59,35.38],'荊州':[112.239741,30.335165],'宜昌':[111.3,30.7],'義烏':[120.06,29.32],'麗水':[119.92,28.45],'洛陽':[112.44,34.7],'秦皇島':[119.57,39.95],'株洲':[113.16,27.83],'石家莊':[114.48,38.03],'萊蕪':[117.67,36.19],'常德':[111.69,29.05],'保定':[115.48,38.85],'湘潭':[112.91,27.87],'金華':[119.64,29.12],'岳陽':[113.09,29.37],'長沙':[113,28.21],'衢州':[118.88,28.97],'廊坊':[116.7,39.53],'菏澤':[115.480656,35.23375],'合肥':[117.27,31.86],'武漢':[114.31,30.52],'大慶':[125.03,46.58]};
citys = list(geoCoordMap.keys())
print(citys)
複製程式碼

建立 city 列

建立city列,如果area裡包含這些城市,就返回這些城市;如果只有省份而無具體城市資訊的,則返回'pro'(其中:'北京', '天津', '上海', '重慶'這些感覺也能演算法城市裡,糾結…),其中;如果是包含海外國家的則返回'unchina';剩下的返回'unknown'

def get_city(area):
    citys = ['海門', '鄂爾多斯', '招遠', '舟山', '齊齊哈爾', '鹽城', '赤峰', '青島', '乳山', '金昌', '泉州', '萊西', '日照', '膠南', '南通', '拉薩', '雲浮', '梅州', '文登', '上海', '攀枝花', '威海', '承德', '廈門', '汕尾', '潮州', '丹東', '太倉', '曲靖', '煙臺', '福州', '瓦房店', '即墨', '撫順', '玉溪', '張家口', '陽泉', '萊州', '湖州', '汕頭', '崑山', '寧波', '湛江', '揭陽', '榮成', '連雲港', '葫蘆島', '常熟', '東莞', '河源', '淮安', '泰州', '南寧', '營口', '惠州', '江陰', '蓬萊', '韶關', '嘉峪關', '廣州', '延安', '太原', '清遠', '中山', '昆明', '壽光', '盤錦', '長治', '深圳', '珠海', '宿遷', '咸陽', '銅川', '平度', '佛山', '海口', '江門', '章丘', '肇慶', '大連', '臨汾', '吳江', '石嘴山', '瀋陽', '蘇州', '茂名', '嘉興', '長春', '膠州', '銀川', '張家港', '三門峽', '錦州', '南昌', '柳州', '三亞', '自貢', '吉林', '陽江', '瀘州', '西寧', '宜賓', '呼和浩特', '成都', '大同', '鎮江', '桂林', '張家界', '宜興', '北海', '西安', '金壇', '東營', '牡丹江', '遵義', '紹興', '揚州', '常州', '濰坊', '重慶', '台州', '南京', '濱州', '貴陽', '無錫', '本溪', '克拉瑪依', '渭南', '馬鞍山', '寶雞', '焦作', '句容', '北京', '徐州', '衡水', '包頭', '綿陽', '烏魯木齊', '棗莊', '杭州', '淄博', '鞍山', '溧陽', '庫爾勒', '安陽', '開封', '濟南', '德陽', '溫州', '九江', '邯鄲', '臨安', '蘭州', '滄州', '臨沂', '南充', '天津', '富陽', '泰安', '諸暨', '鄭州', '哈爾濱', '聊城', '蕪湖', '唐山', '平頂山', '邢臺', '德州', '濟寧', '荊州', '宜昌', '義烏', '麗水', '洛陽', '秦皇島', '株洲', '石家莊', '萊蕪', '常德', '保定', '湘潭', '金華', '岳陽', '長沙', '衢州', '廊坊', '菏澤', '合肥', '武漢', '大慶']
    prolist_less = [ '河北', '山西', '遼寧', '吉林', '江蘇', '浙江', '安徽', '福建', '江西', '山東', '河南', '湖北', '湖南', '廣東', '海南', '四川', '貴州', '雲南', '陝西', '甘肅', '青海', '廣西', '西藏', '寧夏', '新疆', '香港', '澳門', '臺灣', '內蒙古', '黑龍江']
    # 此處 prolist_less 個人喜歡,所以不包含:'北京', '天津', '上海', '重慶' ...
    unchinas = ['英國','美國','日本','瑞士','法國','瑞典','越南','泰國','義大利','加拿大','菲律賓','新加坡','紐西蘭','伊拉克','愛爾蘭','安哥拉','澳大利亞', '大韓民國', '馬來西亞']
    for city in citys:
        if city in area:
            return city
    for pro in prolist_less:
        if pro == area:
            return "pro"
    for unchina in unchinas:
        if unchina in area:
            return "unchina"
    return "unknown"
df['city'] = df.area.apply(get_city)
df[['area','city']]
複製程式碼

檢視所有 unknown 的地理資訊

df_unknown = df[['area','city']][df['city']=='unknown']
print(df_unknown.shape)
unknown_city = list(set(df_unknown.area.values.tolist()))
print(len(unknown_city),unknown_city)
複製程式碼

以下這些是,即非海外,也不是省份,而且不包含 ECharts 那些城市。但幾乎都是省份+城市的格式,所以提取城市比較方便。


遍歷unknown_city,並去掉省份的字首,然後加到unkwns列表中:

prolist_less = [ '河北', '山西', '遼寧', '吉林', '江蘇', '浙江', '安徽', '福建', '江西', '山東', '河南', '湖北', '湖南', '廣東', '海南', '四川', '貴州', '雲南', '陝西', '甘肅', '青海', '廣西', '西藏', '寧夏', '新疆', '香港', '澳門', '內蒙古', '黑龍江']
unkwns = []
others = []
for unkwn in unknown_city:
    for pro in prolist_less:
        if pro in unkwn: #  '青海海南藏族自治州'
            unkwn = unkwn.replace(pro, '')
            unkwns.append(unkwn)
    if unkwn not in unkwns:
        others.append(unkwn)
print(len(unkwns))
print(unkwns) # '青海藏族自治州', '藏族自治州'
print(len(others))
print(others)
複製程式碼

彙總所有城市

unkwns裡面含有xxx自治州的都手動去掉字尾,然後將unkwnscitys合併到一起,all_citys就是我們要統計和進行地圖視覺化的所有城市資料了。以上就是完成了城市資料的提取,讀者可自行按照自己的思路去實現,不必侷限於我的方法。

citys = ['海門', '鄂爾多斯', '招遠', '舟山', '齊齊哈爾', '鹽城', '赤峰', '青島', '乳山', '金昌', '泉州', '萊西', '日照', '膠南', '南通', '拉薩', '雲浮', '梅州', '文登', '上海', '攀枝花', '威海', '承德', '廈門', '汕尾', '潮州', '丹東', '太倉', '曲靖', '煙臺', '福州', '瓦房店', '即墨', '撫順', '玉溪', '張家口', '陽泉', '萊州', '湖州', '汕頭', '崑山', '寧波', '湛江', '揭陽', '榮成', '連雲港', '葫蘆島', '常熟', '東莞', '河源', '淮安', '泰州', '南寧', '營口', '惠州', '江陰', '蓬萊', '韶關', '嘉峪關', '廣州', '延安', '太原', '清遠', '中山', '昆明', '壽光', '盤錦', '長治', '深圳', '珠海', '宿遷', '咸陽', '銅川', '平度', '佛山', '海口', '江門', '章丘', '肇慶', '大連', '臨汾', '吳江', '石嘴山', '瀋陽', '蘇州', '茂名', '嘉興', '長春', '膠州', '銀川', '張家港', '三門峽', '錦州', '南昌', '柳州', '三亞', '自貢', '吉林', '陽江', '瀘州', '西寧', '宜賓', '呼和浩特', '成都', '大同', '鎮江', '桂林', '張家界', '宜興', '北海', '西安', '金壇', '東營', '牡丹江', '遵義', '紹興', '揚州', '常州', '濰坊', '重慶', '台州', '南京', '濱州', '貴陽', '無錫', '本溪', '克拉瑪依', '渭南', '馬鞍山', '寶雞', '焦作', '句容', '北京', '徐州', '衡水', '包頭', '綿陽', '烏魯木齊', '棗莊', '杭州', '淄博', '鞍山', '溧陽', '庫爾勒', '安陽', '開封', '濟南', '德陽', '溫州', '九江', '邯鄲', '臨安', '蘭州', '滄州', '臨沂', '南充', '天津', '富陽', '泰安', '諸暨', '鄭州', '哈爾濱', '聊城', '蕪湖', '唐山', '平頂山', '邢臺', '德州', '濟寧', '荊州', '宜昌', '義烏', '麗水', '洛陽', '秦皇島', '株洲', '石家莊', '萊蕪', '常德', '保定', '湘潭', '金華', '岳陽', '長沙', '衢州', '廊坊', '菏澤', '合肥', '武漢', '大慶']
unkwns = ['眉山', '漯河', '滁州', '景德鎮', '隨州', '遂寧', '三明', '烏蘭察布', '呂梁', '莆田', '河池', '定西', '信陽', '阜新', '廣元', '漢中', '遼陽', '邵陽', '萍鄉', '晉中', '商洛', '樂山', '石河子', '白銀', '池州', '內江', '恩施', '益陽', '伊犁', '張掖', '運城', '綏化', '崇左', '南陽', '達州', '海東', '伊春', '黃石', '龍巖', '蚌埠', '上饒', '駐馬店', '保山', '呼倫貝爾', '安慶', '淮北', '周口', '孝感', '臨滄', '固原', '欽州', '漳州', '巴音郭楞', '宜春', '朝陽', '鷹潭', '婁底', '雅安', '青海', '懷化', '郴州', '許昌', '紅河', '贛州', '朔州', '普洱', '吳忠', '新鄉', '資陽', '雞西', '昌吉', '荊門', '六安', '黃山', '商丘', '武威', '撫州', '湘西', '怒江', '鐵嶺', '百色', '淮南', '廣安', '銅陵', '濮陽', '天水', '襄陽', '南平', '阜陽', '鶴壁', '塔城', '寧德', '大理', '梧州', '衡陽', '晉城', '昭通', '黃岡', '永州', '畢節', '通遼', '玉林', '興安盟', '咸寧']
all_citys = citys + unkwns
複製程式碼

更新 city 列

更新下資料裡的city列,含有這些城市的就返回對應城市,否則不論國外還是省份都統一用others表示:

def get_city(area):
    all_citys = ['海門', '鄂爾多斯', '招遠', '舟山', '齊齊哈爾', '鹽城', '赤峰', '青島', '乳山', '金昌', '泉州', '萊西', 
                 '日照', '膠南', '南通', '拉薩', '雲浮', '梅州', '文登', '上海', '攀枝花', '威海', '承德', '廈門', '汕尾', 
                 '潮州', '丹東', '太倉', '曲靖', '煙臺', '福州', '瓦房店', '即墨', '撫順', '玉溪', '張家口', '陽泉', '萊州',
                 '湖州', '汕頭', '崑山', '寧波', '湛江', '揭陽', '榮成', '連雲港', '葫蘆島', '常熟', '東莞', '河源', '淮安', 
                 '泰州', '南寧', '營口', '惠州', '江陰', '蓬萊', '韶關', '嘉峪關', '廣州', '延安', '太原', '清遠', '中山', 
                 '昆明', '壽光', '盤錦', '長治', '深圳', '珠海', '宿遷', '咸陽', '銅川', '平度', '佛山', '海口', '江門', 
                 '章丘', '肇慶', '大連', '臨汾', '吳江', '石嘴山', '瀋陽', '蘇州', '茂名', '嘉興', '長春', '膠州', '銀川', 
                 '張家港', '三門峽', '錦州', '南昌', '柳州', '三亞', '自貢', '吉林', '陽江', '瀘州', '西寧', '宜賓',
                 '呼和浩特', '成都', '大同', '鎮江', '桂林', '張家界', '宜興', '北海', '西安', '金壇', '東營', '牡丹江', 
                 '遵義', '紹興', '揚州', '常州', '濰坊', '重慶', '台州', '南京', '濱州', '貴陽', '無錫', '本溪', '克拉瑪依', 
                 '渭南', '馬鞍山', '寶雞', '焦作', '句容', '北京', '徐州', '衡水', '包頭', '綿陽', '烏魯木齊', '棗莊', 
                 '杭州', '淄博', '鞍山', '溧陽', '庫爾勒', '安陽', '開封', '濟南', '德陽', '溫州', '九江', '邯鄲', '臨安', 
                 '蘭州', '滄州', '臨沂', '南充', '天津', '富陽', '泰安', '諸暨', '鄭州', '哈爾濱', '聊城', '蕪湖', '唐山', 
                 '平頂山', '邢臺', '德州', '濟寧', '荊州', '宜昌', '義烏', '麗水', '洛陽', '秦皇島', '株洲', '石家莊', 
                 '萊蕪', '常德', '保定', '湘潭', '金華', '岳陽', '長沙', '衢州', '廊坊', '菏澤', '合肥', '武漢', '大慶', 
                 '眉山', '漯河', '滁州', '景德鎮', '隨州', '遂寧', '三明', '烏蘭察布', '呂梁', '莆田', '河池', '定西', 
                 '信陽', '阜新', '廣元', '漢中', '遼陽', '邵陽', '萍鄉', '晉中', '商洛', '樂山', '石河子', '白銀', '池州', 
                 '內江', '恩施', '益陽', '伊犁', '張掖', '運城', '綏化', '崇左', '南陽', '達州', '海東', '伊春', '黃石', 
                 '龍巖', '蚌埠', '上饒', '駐馬店', '保山', '呼倫貝爾', '安慶', '淮北', '周口', '孝感', '臨滄', '固原', '欽州', 
                 '漳州', '巴音郭楞', '宜春', '朝陽', '鷹潭', '婁底', '雅安', '青海', '懷化', '郴州', '許昌', '紅河', '贛州', 
                 '朔州', '普洱', '吳忠', '新鄉', '資陽', '雞西', '昌吉', '荊門', '六安', '黃山', '商丘', '武威', '撫州', 
                 '湘西', '怒江', '鐵嶺', '百色', '淮南', '廣安', '銅陵', '濮陽', '天水', '襄陽', '南平', '阜陽', '鶴壁', 
                 '塔城', '寧德', '大理', '梧州', '衡陽', '晉城', '昭通', '黃岡', '永州', '畢節', '通遼', '玉林', '興安盟', 
                 '咸寧']
    for city in all_citys:
        if city in area:
            return city
    return "other"
df['city'] = df.area.apply(get_city)
df[['area','city']]
複製程式碼

城市分佈

city_count = df.groupby('city')['city'].count().sort_values(ascending=False)
city_count
複製程式碼

城市分佈情況之柱形圖:

from pyecharts import Bar
#bar.use_theme("macarons")
bar = Bar("城市分佈")
bar.add("城市", city_count.index[:30], city_count.values[:30],is_label_show=True,xaxis_interval=0,xaxis_rotate=-45)
bar
複製程式碼

組合成元組,方便後面地圖視覺化時傳入資料:

city_data = list(zip(city_count.index, city_count.values))
city_data
複製程式碼

城市分佈地圖異常

from pyecharts import Geo

geo = Geo("城市分佈情況", "data from SinaNews", title_color="#fff",
          title_pos="center", width=800,
          height=600, background_color='#404a59')
attr, value = geo.cast(city_data)
geo.add("城市分佈情況", attr, value, visual_range=[0, 360], visual_text_color="#fff",
        symbol_size=10, is_visualmap=True)
geo
複製程式碼

一些城市的經緯度資料沒有內建到地圖裡:


報錯資訊說明 pyecharts 裡沒有other的經緯度資訊。

建立nocoor_list列表,用於儲存所有報錯的城市,反覆執行下面兩個 cell 的程式碼,根據地圖報錯提醒,不斷新增城市到nocoor_list列表中,就能得到全部的無經緯度的城市。並將剩下沒報錯的都儲存到city_data 列表中。

city_data = []
nocoor_list = [
    'other','青海','達州','崇左','巴音郭楞','普洱','池州','湘西','伊犁','烏蘭察布','臨滄','海東','眉山',
    '怒江','固原','廣安'
             ]
for item in zip(city_count.index, city_count.values):
    if item[0] in nocoor_list:
        continue  # 跳出迴圈:即遇到不存在經緯度的城市就跳過,不用儲存到 city_data 裡
    city_data.append(item)
city_data
複製程式碼

pyecharts 之城市分佈地圖

順利繪製出城市分佈地圖。

大家一定要自己梳理下整個城市提取和視覺化的過程。最開始也是古柳根據以往實踐的經驗,在不知道 pyecharts 都支援哪些城市(可自行搜尋看看有沒有官方說明)的情況下,選擇去官網複製了那一堆城市資料,然後一步步完成了下來,相對比較順利。

from pyecharts import Geo
geo = Geo("城市分佈情況", "data from SinaNews", title_color="#fff",
          title_pos="center", width=800,
          height=600, background_color='#404a59')
attr, value = geo.cast(city_data)
geo.add("", attr, value, visual_range=[0, 360], visual_text_color="#fff",
        symbol_size=10, is_visualmap=True)
geo
複製程式碼

小結

篇幅所限,後面動態地圖視覺化內容放到下一篇文章裡。先給點提醒用的是WEB 服務API - 百度地圖獲取area列地理位置的經緯度(經過之前文章的學習,想象大家已經能夠輕鬆自如的實現這些步驟了),然後匯出包含經緯度兩列的完整資料到 csv,再根據(送福利)BDP繪製微博轉發動態熱力圖一文,輕鬆實現預期效果。

本系列專案將全面涉及從爬蟲、資料提取與準備、資料異常發現與清洗、分析與視覺化等細節,並將程式碼統一開源在GitHub:DesertsX/gulius-projects ,感興趣的朋友可以先行 star 哈。

本系列文章:
“中國年輕人正帶領國家走向危機”,這鍋背是不背?
手把手教你完成一個資料科學小專案(1):資料爬取
手把手教你完成一個資料科學小專案(2):資料提取、IP 查詢
手把手教你完成一個資料科學小專案(3):資料異常與清洗
手把手教你完成一個資料科學小專案(4):評論數變化情況
手把手教你完成一個資料科學小專案(5):省份提取與視覺化


相關文章