菜鸟笔记Python3——数据可视化(二)世界地图

参考教材

<Python编程——从入门到实践> chapter16 数据可视化

引言

在第二小节里面,我们学习并绘制了一张世界人口分布图,但是在提取相关数据时,我们发现,由于格式不规范,原始数据中的很多地区并没有相应的国别码,在这个练习中,我们需要尽量改善这个问题......

原题

本节制作人口地图时,对于大约12个国家,程序不能自动确定其两个字母的国别码,请找出这些古欧家,在字典 COUNTRIES 中找到他们的国别码,然后对于每个这样的国家,都在原代码中添加一个if-elif代码块,用于返回其国别码

开始!

啧啧啧,才12个国家,手工添加也不是很多嘛!但是,根据上一节被坑的经验,我们还是来看一看到底找不到国别码的地区有多少个好了
先小小地修改一下代码, 把有问题的地区先存到列表 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)

看一看结果:


(ノ=Д=)ノ┻━┻ 这么多的问题地区是什么情况!!!!

好吧,事已至此,我们想想怎么用代码解决这个问题
先观察一下这个 err_country 列表
我们发现在 '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' 里的字符串元素,从第个字符开始查找点号 '.', 空格 ' ' ,还有逗号 ',',一旦找到就停下来,把之前的字符存在新的字符串中,可以用两个循环实现,我们把这个功能做成一个函数:

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: 匹配字典

一样依靠两个循环实现,这里比较麻烦的是要把储存人口数据的 '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'


#创建一个包含人口数量的字典
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')

上一张成果图


比较一下之前的


给自己鼓个掌!!!!!!

PS: 总结

其实还是有没有统计进去的,但是臣妾已经尽力了,如果在提取关键词的时候多提取几个应该就可以把更多的地区统计进来

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,099评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,828评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,540评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,848评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,971评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,132评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,193评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,934评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,376评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,687评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,846评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,537评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,175评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,887评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,134评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,674评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,741评论 2 351

推荐阅读更多精彩内容