真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

談?wù)凱ython實(shí)戰(zhàn)數(shù)據(jù)可視化之pygal模塊(實(shí)戰(zhàn)篇)-創(chuàng)新互聯(lián)

前沿

通過上一節(jié)談?wù)凱ython實(shí)戰(zhàn)數(shù)據(jù)可視化之pygal模塊(基礎(chǔ)篇)的學(xué)習(xí),我們對(duì)pygal模塊的使用有了初步的了解,本節(jié)將以實(shí)戰(zhàn)項(xiàng)目來加深pygal模塊的使用。從網(wǎng)上可以下載JSON格式的人口數(shù)據(jù),并使用json模塊來處理它們,pygal模塊提供了一個(gè)適合初學(xué)者使用的地圖創(chuàng)建工具,我們將使用它來對(duì)人口數(shù)據(jù)進(jìn)行可視化,以探索全球人口的分布情況。針對(duì)JSON格式的人口數(shù)據(jù)文件,可以通過談?wù)凱ython實(shí)戰(zhàn)數(shù)據(jù)可視化之matplotlib模塊(實(shí)戰(zhàn)篇)章節(jié)的配套資源來下載。對(duì)于本人在學(xué)習(xí)和編碼過程種遇到的問題,我都會(huì)逐一解決。

創(chuàng)新互聯(lián)公司主要從事成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、網(wǎng)頁設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)邯鄲,十年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):13518219792

小插曲之執(zhí)行效率

我在學(xué)習(xí)過程中,走各方論壇,發(fā)現(xiàn)一個(gè)有趣的帖子。是針對(duì)Python執(zhí)行效率問題的探究------加一行代碼讓python的運(yùn)行速度提高100倍。什么代碼這么強(qiáng)大?我們測(cè)試看看,從1一直累加到1億。
(1)原始代碼:

import time

def foo(x, y):
    tt = time.time()  # time.time()函數(shù)返回當(dāng)前時(shí)間的時(shí)間戳(1970 紀(jì)元年后經(jīng)過的浮點(diǎn)秒數(shù))
    s = 0
    for i in range(x, y):
        s += i
    print('Time used: {} sec'.format(time.time() - tt))
    return s

print(foo(1, 100000000))

什么是時(shí)間戳?時(shí)間戳表示的是從 1970 年 1 月 1 日 00:00:00 開始按秒計(jì)算的偏移量(time.gmtime(0))此模塊中的函數(shù)無法處理 1970 紀(jì)元年以前的日期和時(shí)間或太遙遠(yuǎn)的未來(處理極限取決于 C 函數(shù)庫,對(duì)于 32 位系統(tǒng)來說,是 2038 年)。
運(yùn)行結(jié)果如下:
談?wù)凱ython實(shí)戰(zhàn)數(shù)據(jù)可視化之pygal模塊(實(shí)戰(zhàn)篇)
(2)加一行代碼,再看看結(jié)果:

from numba import jit  # 添加的代碼
import time

@jit  # 添加的代碼
def foo(x, y):
    tt = time.time()  # time.time()函數(shù)返回當(dāng)前時(shí)間的時(shí)間戳(1970 紀(jì)元年后經(jīng)過的浮點(diǎn)秒數(shù))
    s = 0
    for i in range(x, y):
        s += i
    print('Time used: {} sec'.format(time.time() - tt))
    return s

print(foo(1, 100000000))

運(yùn)行結(jié)果如下:
談?wù)凱ython實(shí)戰(zhàn)數(shù)據(jù)可視化之pygal模塊(實(shí)戰(zhàn)篇)
總結(jié):原始代碼測(cè)試出來的是23sec,加了一行代碼就編程0.25sec了,好像真的變快了將近100倍耶。具體實(shí)現(xiàn)原理貌似有點(diǎn)復(fù)雜,等以后知識(shí)面廣了再研究?jī)?nèi)部原理吧。

JSON格式數(shù)據(jù)

JSON(JavaScript Object Notation) 是一種輕量級(jí)的數(shù)據(jù)交換格式,易于人閱讀和編寫。例如:

[
  {
    "Country Name": "Arab World",
    "Country Code": "ARB",
    "Year": "1960",
    "Value": "96388069"
  },
  {
    "Country Name": "Arab World",
    "Country Code": "ARB",
    "Year": "1961",
    "Value": "98882541.4"
  },
....
....
....

可以看出,這個(gè)文件實(shí)際上就是一個(gè)很長(zhǎng)的Python列表,其中每個(gè)元素都是一個(gè)包含四個(gè)鍵的字典:國(guó)家名、國(guó)別碼、年份以及表示人口數(shù)量的值。

提取JSON格式文件的數(shù)據(jù)

在工程目錄下,創(chuàng)建一個(gè)world_population.py文件,并將population_data.json格式文件放到工程目錄下。然后編寫以下代碼嘗試提取經(jīng)json模塊轉(zhuǎn)化后的格式數(shù)據(jù):

# 導(dǎo)入json模塊分析JSON格式文件
import json

filename = 'population_data.json'
with open(filename) as f:
    # 函數(shù)json.load()將數(shù)據(jù)(文件對(duì)象)轉(zhuǎn)換為Python能處理的格式,
    pop_data = json.load(f)  # pop_data是一個(gè)列表,每個(gè)元素都包含一個(gè)四個(gè)鍵的字典

for pop_dict in pop_data:
    # 只刷選出2010年份的國(guó)家人口數(shù)量
    if pop_dict['Year'] == '2010':
        # 將每個(gè)國(guó)家的國(guó)家名、國(guó)家人口數(shù)保存并打印輸出
        country_name = pop_dict['Country Name']
        population = int(float(pop_dict['Value']))  
        print(country_name + ":" + str(population))

運(yùn)行結(jié)果如下:
談?wù)凱ython實(shí)戰(zhàn)數(shù)據(jù)可視化之pygal模塊(實(shí)戰(zhàn)篇)
需要注意的是,上面代碼獲取pop_dict['Value']的值是一個(gè)字符串,而后面我們進(jìn)行數(shù)據(jù)可視化時(shí),人口數(shù)量必須使用數(shù)值才行,所以,我們先轉(zhuǎn)化為float類型,再轉(zhuǎn)化為int類型。為什么不直接轉(zhuǎn)化為Int類型?這是因?yàn)楫?dāng)for循環(huán)遍歷到人口數(shù)值是包含小數(shù)點(diǎn)的字符串(例如:'1127437398.85751')時(shí),Python不能直接轉(zhuǎn)化為整數(shù),不然會(huì)出現(xiàn)類似下面的報(bào)錯(cuò):
談?wù)凱ython實(shí)戰(zhàn)數(shù)據(jù)可視化之pygal模塊(實(shí)戰(zhàn)篇)
為了消除這種錯(cuò)誤,正確的做法是先將'1127437398.85751'字符串轉(zhuǎn)化為float類型(1127437398.85751),再轉(zhuǎn)化為Int類型(1127437398)。

獲取兩個(gè)字母的國(guó)別碼

Pygal中的地圖制作工具要求數(shù)據(jù)為特定的格式:用國(guó)別碼表示國(guó)家,以及用數(shù)字表示人口數(shù)量。最重要的問題是,population_data.json中包含的是三個(gè)字母的國(guó)別碼,但Pygal使用兩個(gè)字母的國(guó)別碼(存儲(chǔ)在i18n模塊中,其實(shí)是在該模塊的一個(gè)字典COUNTRIES里,該字典包含的鍵和值分別為兩個(gè)字母的國(guó)別碼和國(guó)家名)來表示國(guó)家。所以我們要解決的問題就是根據(jù)國(guó)家名在i18n模塊中的字典COUNTRIES里獲取兩個(gè)字母的國(guó)別碼。這樣就可以在世界地圖上表示的國(guó)別碼和人口數(shù)量分別使用字典COUNTRIES里的兩個(gè)字母的國(guó)別碼和population_data.json文件里的人口數(shù)量。好了,說了解決問題的流程,現(xiàn)在我們嘗試使用i18n模塊來獲取字典COUNTRIES里的鍵和值,先在工程目錄下創(chuàng)建一個(gè)country_codes.py文件。
需要注意的是書本P327頁的16.2.4小節(jié),導(dǎo)入i18n模塊的方法對(duì)于現(xiàn)在來說已經(jīng)不適用了。如果導(dǎo)入模塊的代碼寫“from pygal.i18n import COUNTRIES”就會(huì)報(bào)以下的錯(cuò)誤:
談?wù)凱ython實(shí)戰(zhàn)數(shù)據(jù)可視化之pygal模塊(實(shí)戰(zhàn)篇)
應(yīng)該改為“from pygal_maps_world.i18n import COUNTRIES”才行。
代碼如下:

# 返回il8n模塊中COUNTRIES字典中對(duì)應(yīng)國(guó)家名的國(guó)別碼
from pygal_maps_world.i18n import COUNTRIES

def get_country_code(country_name):
    for code, name in COUNTRIES.items():  # 返回字典的所有鍵值對(duì)
        if name == country_name:  # 根據(jù)國(guó)家名返回兩個(gè)字母的國(guó)別碼
            return code
    return None  # 如果沒有找到則返回None

修改world_population.py文件的代碼,代碼如下:

# 導(dǎo)入json模塊分析JSON格式文件
import json
from country_codes import get_country_code

filename = 'population_data.json'
with open(filename) as f:
    # 函數(shù)json.load()將數(shù)據(jù)(文件對(duì)象)轉(zhuǎn)換為Python能處理的格式,
    pop_data = json.load(f)  # pop_data是一個(gè)列表,每個(gè)元素都包含一個(gè)四個(gè)鍵的字典

for pop_dict in pop_data:
    # 只刷選出2010年份的國(guó)家人口數(shù)量
    if pop_dict['Year'] == '2010':
        # 將每個(gè)國(guó)家的國(guó)家名、國(guó)家人口數(shù)保存并打印輸出
        country_name = pop_dict['Country Name']
        population = int(float(pop_dict['Value']))
        code = get_country_code(country_name)  # 將population_data.json文件獲取的國(guó)家名傳入函數(shù),若存在則返回對(duì)應(yīng)的國(guó)別碼
        if code:  # 如果存在則輸出國(guó)家名對(duì)應(yīng)的國(guó)別碼
            print(code + ":" + str(population))
        else:
            print('ERROR - '+country_name)

運(yùn)行結(jié)果如下:
談?wù)凱ython實(shí)戰(zhàn)數(shù)據(jù)可視化之pygal模塊(實(shí)戰(zhàn)篇)
從上圖可以看出,其實(shí)有相當(dāng)一部分國(guó)家沒有對(duì)應(yīng)的國(guó)別碼,導(dǎo)致顯示錯(cuò)誤消息的原因有兩個(gè)。第一,并非所有人口數(shù)量都是國(guó)家,有些是地區(qū)和經(jīng)濟(jì)類群。第二,有些統(tǒng)計(jì)數(shù)據(jù)使用了不同的完整國(guó)家名,所以識(shí)別不到。

制作世界地圖

有了兩個(gè)字母的國(guó)別碼后,我們可以進(jìn)行以下步驟:
1.構(gòu)造虛擬數(shù)據(jù)制作一個(gè)世界地圖顯示指定了國(guó)別碼的國(guó)家有哪些,還有呈現(xiàn)人口數(shù)量,來感受一下世界地圖的宏偉。
2.繪制一個(gè)2010年真實(shí)數(shù)據(jù)的完整的世界人口地圖圖表。
3.根據(jù)人口數(shù)量將國(guó)家分組
4.世界人口地圖圖表進(jìn)行樣式優(yōu)化處理。
(1)制作一個(gè)模擬數(shù)據(jù)世界地圖
在此之前,P329頁16.2.5小節(jié)的代碼中調(diào)用函數(shù)創(chuàng)建世界地圖的方法對(duì)于現(xiàn)在也不適用了,如果代碼寫“wm = pygal.Worldmap() ”會(huì)報(bào)以下錯(cuò)誤
談?wù)凱ython實(shí)戰(zhàn)數(shù)據(jù)可視化之pygal模塊(實(shí)戰(zhàn)篇)
將代碼改為“wm = pygal.maps.world.World()”就可以通過了。代碼如下:

import pygal

wm = pygal.maps.world.World()  # 創(chuàng)建一個(gè)實(shí)例
wm.title = 'North,Central America'

# 利用add函數(shù)添加標(biāo)簽和國(guó)家名還有人口數(shù)量,若參數(shù)2是一個(gè)列表(只有國(guó)家名,沒有指定人口數(shù)量),默認(rèn)指定人口數(shù)量為1,那么就是使用同一種顏色,并且顏色深淺一樣,除非人口數(shù)量不同。
# 而參數(shù)2如果是一個(gè)字典,那么說明指定國(guó)家名的同時(shí)還指定了人口數(shù)量,那么雖然使用同一種類型顏色,但根據(jù)人口數(shù)量的多少?zèng)Q定顏色的深淺
wm.add('North America', {'ca': 10000, 'mx': 20000, 'us': 30000})
wm.add('Central America', {'bz': 40000, 'cr': 50000, 'gt': 60000, 'hn': 70000, 'ni': 80000, 'pa': 90000, 'sv': 100000})

wm.render_to_file('americas.svg')

將americas.svg放入瀏覽器中顯示,運(yùn)行結(jié)果如下:
談?wù)凱ython實(shí)戰(zhàn)數(shù)據(jù)可視化之pygal模塊(實(shí)戰(zhàn)篇)
上面的人口數(shù)據(jù)純屬虛構(gòu)。從上圖可以看出,將鼠標(biāo)移至國(guó)家上方便可顯示國(guó)家名和人口數(shù),North America的三個(gè)國(guó)家分別使用同一種、但深淺不一的顏色來表示,其中人口數(shù)量越大,顏色越深。而Central America的多個(gè)國(guó)家也是同樣如此。
(2)繪制完整的世界人口地圖
要呈現(xiàn)其他國(guó)家的人口數(shù)量,需要將前面處理的數(shù)據(jù)(兩個(gè)字母的國(guó)別碼和對(duì)應(yīng)國(guó)家的人口數(shù)量)轉(zhuǎn)換為Pygal要求的字典格式(即作為實(shí)參傳入add函數(shù)的第二個(gè)形參)。代碼如下:

import json
import pygal
from country_codes import get_country_code

filename = 'population_data.json'
with open(filename) as f:
    # 函數(shù)json.load()將數(shù)據(jù)(文件對(duì)象)轉(zhuǎn)換為Python能處理的格式,
    pop_data = json.load(f)  # pop_data是一個(gè)列表,每個(gè)元素都包含一個(gè)四個(gè)鍵的字典

cc_populations = {}
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_populations[code] = population

wm = pygal.maps.world.World()
wm.title = 'World Population in 2010,by Country'
wm.add('2010',cc_populations)

wm.render_to_file('world_population.svg')

運(yùn)行結(jié)果如下:
談?wù)凱ython實(shí)戰(zhàn)數(shù)據(jù)可視化之pygal模塊(實(shí)戰(zhàn)篇)
根據(jù)上面可以總結(jié)出:若將整個(gè)世界所有國(guó)家的國(guó)別碼和人口數(shù)量都放進(jìn)一個(gè)字典里,再調(diào)用一個(gè)add函數(shù)添加進(jìn)世界地圖,那么就會(huì)把這個(gè)字典當(dāng)成一個(gè)組,那么在世界地圖顯示時(shí),使用同一種、但深淺不一的紅顏色來表示,其中人口數(shù)量越大,顏色越深。再想想,這可不太行,因?yàn)檎w來看,很難反映其人口數(shù)量的差別,為了解決這個(gè)問題,我們究其根源,主要是我們只使用了一個(gè)字典和只調(diào)用了一個(gè)add函數(shù)來表示整個(gè)世界的原因?qū)е骂伾珕我?,解決辦法是我們可以對(duì)其進(jìn)行分組處理,人口數(shù)量多的為一組,人口數(shù)量中等的為一組,人口數(shù)量少的為一組,那么就分為三組了。

根據(jù)人口數(shù)量將國(guó)家分組

針對(duì)上一節(jié)結(jié)論的分析,我們這一小節(jié)將采用分組的方式反映人口數(shù)量的差別。根據(jù)人口數(shù)量分成三組:少于1000萬的、介于1000萬和10億之間的以及超過10億的。
代碼如下:

import json
import pygal
from country_codes import get_country_code

filename = 'population_data.json'
with open(filename) as f:
    # 函數(shù)json.load()將數(shù)據(jù)(文件對(duì)象)轉(zhuǎn)換為Python能處理的格式,
    pop_data = json.load(f)  # pop_data是一個(gè)列表,每個(gè)元素都包含一個(gè)四個(gè)鍵的字典

cc_populations = {}
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_populations[code] = population

# 根據(jù)人口數(shù)量將所有的國(guó)家分成三組
cc_pops_1, cc_pops_2, cc_pops_3 = {}, {}, {}
for cc, pop in cc_populations.items():
    if pop < 10000000:
        cc_pops_1[cc] = pop
    elif pop < 1000000000:
        cc_pops_2[cc] = pop
    else:
        cc_pops_3[cc] = pop

wm = pygal.maps.world.World()  # 創(chuàng)建一個(gè)實(shí)例
wm.title = 'World Population in 2010,by Country'
wm.add('0-10m', cc_pops_1)
wm.add('10m-1bn', cc_pops_2)
wm.add('>1bn', cc_pops_3)

wm.render_to_file('world_population.svg')

運(yùn)行結(jié)果如下:
談?wù)凱ython實(shí)戰(zhàn)數(shù)據(jù)可視化之pygal模塊(實(shí)戰(zhàn)篇)
從上圖可以看出,世界地圖使用三種不同的顏色,更直觀地看出人口數(shù)量的差別,在每組中,各個(gè)國(guó)家都按人口從少到多以淺到深的顏色。其中中國(guó)和印度是大于10億人的國(guó)家。

世界人口地圖圖表進(jìn)行樣式優(yōu)化處理

前面的案例,采用默認(rèn)的顏色設(shè)置不怎么好看,我們可以使用Pygal樣式設(shè)置指令來調(diào)整顏色。Pygal樣式存儲(chǔ)在模塊style中,我們從這個(gè)模塊中導(dǎo)入了RotateStyle類,創(chuàng)建這個(gè)類的實(shí)例時(shí),需要提供一個(gè)實(shí)參 —— 十六進(jìn)制的 RGB 顏色。十六進(jìn)制格式 的 RGB 顏色是一個(gè)以井號(hào)( # )打頭的字符串,后面跟著 6 個(gè)字符,其中前兩個(gè)字符表示紅色分量,接下來的兩個(gè)表示綠色分量,最后兩個(gè)表示藍(lán)色分量。每個(gè)分量的取值范圍為 00 (沒有相應(yīng)的顏色) ~FF (包含最多的相應(yīng)顏色)。Pygal 通常默認(rèn)使用較暗的顏色主題。使用 LightColorizedStyle 加亮了地圖的顏色。
代碼如下:

import json
import pygal
from country_codes import get_country_code
from pygal.style import LightColorizedStyle as LCS,RotateStyle as RS  # 導(dǎo)入RotateStyle和 LightColorizedStyle,并取了別名,后面調(diào)用就采用別名,方便多了

filename = 'population_data.json'
with open(filename) as f:
    # 函數(shù)json.load()將數(shù)據(jù)(文件對(duì)象)轉(zhuǎn)換為Python能處理的格式,
    pop_data = json.load(f)  # pop_data是一個(gè)列表,每個(gè)元素都包含一個(gè)四個(gè)鍵的字典

cc_populations = {}
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_populations[code] = population

# 根據(jù)人口數(shù)量將所有的國(guó)家分成三組
cc_pops_1, cc_pops_2, cc_pops_3 = {}, {}, {}
for cc, pop in cc_populations.items():
    if pop < 10000000:
        cc_pops_1[cc] = pop
    elif pop < 1000000000:
        cc_pops_2[cc] = pop
    else:
        cc_pops_3[cc] = pop

wm_style = RS('#336699',base_style=LCS)  # 一個(gè)樣式對(duì)象,參數(shù)指定一個(gè)十六進(jìn)制的RGB顏色
wm = pygal.maps.world.World(style=wm_style)  # 創(chuàng)建一個(gè)實(shí)例,并傳入一個(gè)指定了顏色的樣式對(duì)象wm_style
wm.title = 'World Population in 2010,by Country'
wm.add('0-10m', cc_pops_1)
wm.add('10m-1bn', cc_pops_2)
wm.add('>1bn', cc_pops_3)

wm.render_to_file('world_population.svg')

運(yùn)行結(jié)果如下:
談?wù)凱ython實(shí)戰(zhàn)數(shù)據(jù)可視化之pygal模塊(實(shí)戰(zhàn)篇)

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。


分享標(biāo)題:談?wù)凱ython實(shí)戰(zhàn)數(shù)據(jù)可視化之pygal模塊(實(shí)戰(zhàn)篇)-創(chuàng)新互聯(lián)
文章起源:http://weahome.cn/article/coccis.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部