菜鳥筆記Python3——數據可視化(二)世界地圖

參考教材

<Python編程——從入門到實踐> chapter16 數據可視化

引言

在第二小節(jié)里面,我們學習并繪制了一張世界人口分布圖,但是在提取相關數據時菌赖,我們發(fā)現梅肤,由于格式不規(guī)范司蔬,原始數據中的很多地區(qū)并沒有相應的國別碼,在這個練習中姨蝴,我們需要盡量改善這個問題......

原題

本節(jié)制作人口地圖時俊啼,對于大約12個國家,程序不能自動確定其兩個字母的國別碼左医,請找出這些古歐家授帕,在字典 COUNTRIES 中找到他們的國別碼,然后對于每個這樣的國家浮梢,都在原代碼中添加一個if-elif代碼塊跛十,用于返回其國別碼

開始!

嘖嘖嘖秕硝,才12個國家芥映,手工添加也不是很多嘛!但是远豺,根據上一節(jié)被坑的經驗奈偏,我們還是來看一看到底找不到國別碼的地區(qū)有多少個好了
先小小地修改一下代碼, 把有問題的地區(qū)先存到列表 err_country 中

for pop_dict in pop_data:
    if pop_dict['Year'] == '2010':
        country_name = pop_dict['Country Name']
        population = int(float(pop_dict['Value']))
        code = get_country_code(country_name)
        if code:
            cc_population[code] = population
        if code == None:
            err_country.append(country_name)
            err_pop.append(population)
print(err_country)

看一看結果:


(ノ=Д=)ノ┻━┻ 這么多的問題地區(qū)是什么情況!Gぁ>础!

好吧棺滞,事已至此裁蚁,我們想想怎么用代碼解決這個問題
先觀察一下這個 err_country 列表
我們發(fā)現在 'World' 這個詞之前,都是一些一眼就能看出不是國家的元素
先把它們全都刪掉再說继准!
先貼代碼:

err_pop = []
key = True
for pop_dict in pop_data:
    if pop_dict['Year'] == '2010':
        country_name = pop_dict['Country Name']
        population = int(float(pop_dict['Value']))
        code = get_country_code(country_name)
        if code:
            cc_population[code] = population
        if (code == None) and (key == False):
            err_country.append(country_name)
            err_pop.append(population)
        if country_name == 'World':
            key = False

用一個 key 來檢測是否讀取到了 'World'枉证,只有在 'World‘ 之后的元素才被存進 列表 err_country 中,同時锰瘸, 我們用一個列表 err_pop 來儲存對應的人口信息
運行一下:

很好刽严!前面那些太明顯的地名已經沒了

在 COUNTRIES 字典中找到對應的國別碼

雖然剔除了很多信息,但是剩下的地名依然很多,還是要依靠代碼找到他們對應的國別碼

分析一下

程序之所以找不到這些地名對應的國別碼舞萄,是因為它們的名字跟字典 COUNTRIES 里的標準名稱不匹配眨补,要解決這個問題,一個簡單的思路是 我們只提取 這些地名的部分單詞作為關鍵字倒脓,然后用這些關鍵字去跟字典 COUNTRIES 進行匹配撑螺, 可以觀察到,大部分的地名的關鍵字都在 第一個單詞崎弃,少數以 'St.' 開頭的地名 關鍵字在 'St.' 后的第一個單詞
這樣甘晤,大致的思路就出來了

思路:提取關鍵字-> 匹配字典->加上人口信息做成新的字典

step 1: 關鍵字的提取

很簡單,對于每一個 'err_country' 里的字符串元素饲做,從第個字符開始查找點號 '.'线婚, 空格 ' ' ,還有逗號 ',',一旦找到就停下來盆均,把之前的字符存在新的字符串中塞弊,可以用兩個循環(huán)實現,我們把這個功能做成一個函數:

def get_first_word(name):
    new_name = ''
    for letter in name:
        new_name += letter
        if letter == ','or letter == ' ' or letter == '.':
            new_name = new_name[:-1] #刪掉最后的 , 空格 或者 .
            break
    return new_name

step 2: 匹配字典

一樣依靠兩個循環(huán)實現泪姨,這里比較麻煩的是要把儲存人口數據的 'err_pop' 里面的數據 對應地 放到新字典里面游沿,本人沒什么好方法,用了最笨的計數法肮砾,在歷遍 err_country 的同時诀黍, 用 count 控制 err_pop 保持同步

def get_pop(filename):
--snip--
    new_country = {}
    count = -1
    for err_country in new_err:
        count += 1
        for code , country in COUNTRIES.items():
            if err_country in country:
                new_country[code] = err_pop[count]
--snip--

step 3:合成一個新的字典

這一步算是最簡單的了,不廢話仗处,直接上

    for code, pop in new_country.items():
        cc_population[code] = pop

完整的代碼在這里

#! /usr/bin/python <br> # -*- coding: utf8 -*-
import json
from country_codes import get_country_code
import string as s
from pygal.maps.world import COUNTRIES

def get_first_word(name):
    new_name = ''
    for letter in name:
        new_name += letter
        if letter == ','or letter == ' ' or letter == '.':
            new_name = new_name[:-1] #刪掉最后的 , 空格 或者 .
            break
    return new_name

def get_pop(filename):
    filename = 'population_data.json'
    cc_population = {}
    err_country = []
    with open(filename) as f:
        pop_data = json.load(f)
    err_pop = []
    key = True
    for pop_dict in pop_data:
        if pop_dict['Year'] == '2010':
            country_name = pop_dict['Country Name']
            population = int(float(pop_dict['Value']))
            code = get_country_code(country_name)
            if code:
                cc_population[code] = population
            if (code == None) and (key == False):
                err_country.append(country_name)
                err_pop.append(population)
            if country_name == 'World':
                key = False
    print(err_country)
    new_err = []
    for country_name in err_country:
        new_name = get_first_word(country_name)
        if new_name == 'St':
           new_name = country_name[4:]
           new_name = get_first_word(new_name)
        new_err.append(new_name)

    new_country = {}
    count = -1
    for err_country in new_err:
        count += 1
        for code , country in COUNTRIES.items():
            if err_country in country:
                new_country[code] = err_pop[count]

    for code, pop in new_country.items():
        cc_population[code] = pop

    return cc_population

然后繪圖文件那里也要做相應的修改眯勾,很簡單,直接貼完整的代碼好了

#! /usr/bin/python <br> # -*- coding: utf8 -*-
import pygal
import json
from country_codes import get_country_code
from pygal.style import RotateStyle
from pygal.style import LightColorizedStyle
from countries import get_pop
#將數據加載到一個列表中
filename = 'population_data.json'


#創(chuàng)建一個包含人口數量的字典
cc_population = {}
cc_pop1,cc_pop2,cc_pop3 = {},{},{}

cc_population = get_pop(filename)

for cc,pop in cc_population.items():
    if pop < 10000000:
        cc_pop1[cc] = pop
    elif pop < 1000000000:
        cc_pop2[cc] = pop
    else:
        cc_pop3[cc] = pop
wm_style = RotateStyle('#226699',base_style=LightColorizedStyle)
wm = pygal.maps.world.World(style=wm_style)
wm.title = 'World Population in 2010, by Country'
wm.add('0-10m',cc_pop1)
wm.add('10m-1bn',cc_pop2)
wm.add('>1bn',cc_pop3)

wm.render_to_file('world_population_v10.svg')

上一張成果圖


比較一下之前的


給自己鼓個掌=帷V渚O庵?醯怠!歇拆!

PS: 總結

其實還是有沒有統(tǒng)計進去的鞋屈,但是臣妾已經盡力了,如果在提取關鍵詞的時候多提取幾個應該就可以把更多的地區(qū)統(tǒng)計進來

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末故觅,一起剝皮案震驚了整個濱河市厂庇,隨后出現的幾起案子,更是在濱河造成了極大的恐慌输吏,老刑警劉巖权旷,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異贯溅,居然都是意外死亡拄氯,警方通過查閱死者的電腦和手機躲查,發(fā)現死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來译柏,“玉大人镣煮,你說我怎么就攤上這事”陕螅” “怎么了典唇?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長胯府。 經常有香客問我介衔,道長,這世上最難降的妖魔是什么骂因? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任夜牡,我火速辦了婚禮,結果婚禮上侣签,老公的妹妹穿的比我還像新娘塘装。我一直安慰自己,他們只是感情好影所,可當我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布蹦肴。 她就那樣靜靜地躺著,像睡著了一般猴娩。 火紅的嫁衣襯著肌膚如雪阴幌。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天卷中,我揣著相機與錄音矛双,去河邊找鬼。 笑死蟆豫,一個胖子當著我的面吹牛议忽,可吹牛的內容都是我干的。 我是一名探鬼主播十减,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼栈幸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了帮辟?” 一聲冷哼從身側響起速址,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎由驹,沒想到半個月后芍锚,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年并炮,在試婚紗的時候發(fā)現自己被綠了蒿赢。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡渣触,死狀恐怖羡棵,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情嗅钻,我是刑警寧澤皂冰,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站养篓,受9級特大地震影響秃流,放射性物質發(fā)生泄漏。R本人自食惡果不足惜柳弄,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一舶胀、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧碧注,春花似錦嚣伐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至逝变,卻和暖如春基茵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背壳影。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工拱层, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人宴咧。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓根灯,卻偏偏與公主長得像,于是被迫代替她去往敵國和親悠汽。 傳聞我的和親對象是個殘疾皇子箱吕,可洞房花燭夜當晚...
    茶點故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內容