![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/dc86a81b7e06e2dfa0595cc6a18e014794a317616b97ec31703063a65cad99e2.png)
本文以一款阿里雲市場歷史天氣查詢產品為例,為你逐步介紹如何用 Python 呼叫 API 收集、分析與視覺化資料。希望你舉一反三,輕鬆應對今後的 API 資料收集與分析任務。
雷同
上週的研究生課,學生分組展示實踐環節第二次作業,主題是利用 API 獲取、分析與視覺化資料。
大家做的內容,確實五花八門。
例如這個組,調查物件是動畫片《小豬佩奇》(英文名 “Peppa Pig”,又譯作《粉紅豬小妹》)。這部片子據說最近很火。
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/b528da387cf3c6189c5c99ffdc63dafb94a0c45599e388b2dda2add15e1b9511.jpg)
猜猜看,下面這一組調查物件是什麼?
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/2369a1ee980508beb0cbe3e579df7e17250baa9ce3350749ebddf285e1306569.jpg)
沒錯,是《權力的遊戲》(Game of Thrones)。一部很好看的美劇。
主題豐富多彩,做得有聲有色。
作為老師,我在下面,應該很開心吧?
不,我簡直哭笑不得。
14個組中,有一多半都和他們一樣,做的是維基百科頁面訪問量分析。
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/17a4eef787f6caeb18e3a4e5efadbc9dba522505ee421a27c5f2e41bf0368755.jpg)
為什麼會這樣呢?
因為我在佈置作業的時候,很貼心地給了一個樣例,是我之前寫的一篇教程《如何用R和API免費獲取Web資料?》。
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/924526dbe3565e48840b6162f5664242d0825dc8b898e86ac02944b149e5da31.png)
於是,他們就都用 R 語言,來分析維基百科頁面訪問量了。
這些同學是不是太懶惰了?
聽了他們的講述,我發覺,其中不少同學,是非常想做些新東西的。
他們找了國內若干個雲市場,去找 API 產品。
其中要價過高的 API ,被他們自動過濾了。
可即適合練手的低價或免費 API ,也不少。
問題是,他們花了很長時間,也沒能搞定。
考慮到作業展示日程迫近,他們只好按照我的教程,去用 R 分析維基百科了。
於是,多組作業,都雷同。
講到這裡,他們一副不好意思的表情。
我卻發覺,這裡蘊藏著一個問題。
幾乎所有國內雲市場的 API 產品,都有豐富的文件。不少還乾脆給出了各種程式語言對應呼叫程式碼。
既然示例程式碼都有了,為什麼你還做不出來呢?
下課後,我讓有疑問的同學留下,我帶著他們實際測試了一款 API 產品,嘗試找到讓他們遭遇困境的原因。
市場
我們嘗試的,是他們找到的阿里雲市場的一款 API 產品,提供天氣資料。
它來自於易源資料,連結在這裡。
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/8be3b500142e5de60b6f60d3fcfd5935704bcd8c97bb281e19337aa398bbbfa1.png)
這是一款收費 API ,100次呼叫的價格為1分錢。
作為作業練習,100次呼叫已經足夠了。
這價格,他們表示可以接受。
我自己走了一遍流程。
點選“立即購買”按鈕。
你會被引領到付費頁面。如果你沒有登入,可以根據提示用淘寶賬號登入。
支付1分錢以後,你會看到如下的成功提示。
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/dc1500ec27349ddd346b697823ed8e0e0ba7b3703cae07982a2fda1ce90e3b5b.png)
之後,系統會提示給你一些非常重要的資訊。
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/0f4418435acfc80a2452fe74df88f6ebc8facf40e7d8fb210db6753ec4c86aa2.png)
注意上圖中標紅的欄位。
這是你的AppCode,是後面你呼叫 API 介面獲取資料,最為重要的身份認證手段,請點選“複製”按鈕把它儲存下來。
點選上圖中的商品名稱連結,回到產品介紹的頁面。
這個產品的 API 介面,提供多種資料獲取功能。
學生們嘗試利用的,是其中“利用id或地名查詢歷史天氣”一項。
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/0fd01c1109de430aa1a4701122c4d7c73ee527d6c0a4aeb1531600a469315bed.png)
請注意這張圖裡,有幾樣重要資訊:
- 呼叫地址:這是我們訪問 API 的基本資訊。就好像你要去見朋友,總得知道見面的地址在哪裡;
- 請求方式:本例中的 GET ,是利用 HTTP 協議請求傳遞資料的主要形式之一;
- 請求引數:這裡你要提供兩個資訊給 API 介面,一是“地區名稱”或者“地區id”(二選一),二是月份資料。需注意格式和可供選擇的時間範圍。
我們往下翻頁,會看到請求示例。
預設的請求示例,是最簡單的 curl 。
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/e42874bf29364bc90b098ccce6d80bb2c0e0b52dafc1f49754a899df21565940.png)
如果你的作業系統裡面已經安裝了 curl (沒有安裝的話,可以點選這個連結,尋找對應的作業系統版本下載安裝),嘗試把上圖中 curl 開頭的那一行程式碼拷貝下來,複製到文字編輯器裡面。
就像這樣:
curl -i -k --get --include 'https://ali-weather.showapi.com/weatherhistory?area=%E4%B8%BD%E6%B1%9F&areaid=101291401&month=201601' -H 'Authorization:APPCODE 你自己的AppCode'
複製程式碼
然後,一定要把其中的“你自己的AppCode”這個字串,替換為你真實的 AppCode 。
把替換好的語句複製貼上到終端視窗裡面執行。
執行結果,如下圖所示:
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/ddc6641da8131494fcc106ac304e88b2fa0d04c2c2bcbf73277daa5a7c5d835f.png)
看見視窗下方包含中文的資料了嗎?
利用 API 獲取資料,就是這麼簡單。
既然終端執行一條命令就可以,那我們幹嘛還要程式設計呢?
好問題!
因為我們需要的資料,可能不是一次呼叫就能全部獲得。
你需要重複多次呼叫 API ,而且還得不斷變化引數,積累獲得資料。
每次若是都這樣手動執行命令,效率就太低了。
API 的提供方,會為使用者提供詳細的文件與說明,甚至還包括樣例。
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/9b3fac1f95ca2b9b4470ababfe6d1413a1557a6208d483c62c0280ee86d39945.png)
上圖中,除了剛才我們使用的 curl ,還包括以下語言訪問 API 介面的樣例說明:
- Java
- C#
- PHP
- Python
- Object C
我們以 Python 作為例子,點開標籤頁看看。
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/dc892a44b52c422d10c27b1efdc09268a58c3f58dd950fb5cda4b43fb0288fcc.png)
你只需要把樣例程式碼全部拷貝下來,用文字編輯器儲存為“.py”為副檔名的 Python 指令碼檔案,例如 demo.py 。
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/640d3c37275201be7e454e4bc3be2a3848e8125f2db3edfa80c00350c62de352.png)
再次提醒,別忘了,把其中“你自己的AppCode”這個字串,替換為你真實的 AppCode,然後儲存。
在終端下,執行:
python demo.py
複製程式碼
如果你用的是 2.7 版本的 Python ,就立即可以正確獲得結果了。
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/befe937f1dba550233806a55740425bf34cbc1decee0c3ec497ca109b09c4b7c.png)
為什麼許多學生做不出來結果呢?
我讓他們實際跑了一下,發現確實有的學生粗心大意,忘了替換自己的 AppCode 。
但是大部分同學,由於安裝最新版本的 Anaconda (Python 3.6版),都遇到了下面的問題:
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/bb6d72bd00010e537b9472c0d8c066f8c804d41c21f314107868da28219af49f.png)
你可能會認為這是因為沒有正確安裝 urllib2 模組,於是執行
pip install urllib2
複製程式碼
你可能會看到下面的報錯提示:
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/41fe1d5e552e764c1c28319018bcd89a07101524cb321ec4f35cf1aa79882f2a.png)
你也許嘗試去掉版本號,只安裝 urllib,即:
pip install urllib
複製程式碼
但是結果依然不美妙:
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/8e8d070eebe843a57c20e8a697995b2d99394a85d3eb00da3b19b52638ad265c.png)
有些 Python 開發者看到這裡,可能會嘲笑我們:Python 3版本里面,urllib 被拆分了啊!地球人都知道,你應該……
請保持一顆同理心。
想想一個普通使用者,憑什麼要了解不同版本 Python 之間的語句差異?憑什麼要對這種版本轉換的解決方式心裡有數?
在他們看來,官方網站提供的樣例,就應該是可以執行的。報了錯,又不能通過自己的軟體包安裝“三板斧”來解決,就會慌亂和焦慮。
更進一步,他們也不太瞭解 JSON 格式。
雖然,JSON已是一種非常清晰的、人機皆可通讀的資料儲存方式了。
他們想了解的,是怎麼把問題遷移到自己能夠解決的範圍內。
例如說,能否把 JSON 轉換成 Excel 形式的資料框?
如果可以,他們就可以呼叫熟悉的 Excel 命令,來進行資料篩選、分析與繪圖了。
他們還會想,假如 Python 本身,能一站式完成資料讀取、整理、分析和視覺化全流程,那自然更好。
但是,樣例,樣例在哪裡呢?
在我《Python程式設計遇問題,文科生怎麼辦?》一文中,我曾經提到過,這種樣例,對於普通使用者的重要性。
沒有“葫蘆”,他們又如何“照葫蘆畫瓢”呢?
既然這個例子中,官方文件沒有提供如此詳細的程式碼和講解樣例,那我就來為你繪製個“葫蘆”吧。
下面,我給你逐步展示,如何在 Python 3 下,呼叫該 API 介面,讀取、分析資料,和繪製圖形。
環境
首先我們來看看程式碼執行環境。
前面提到過,如果樣例程式碼的執行環境,和你本地的執行環境不一,計時程式碼本身沒問題,也無法正常執行。
所以,我為你構建一個雲端程式碼執行環境。(如果你對這個程式碼執行環境的構建過程感興趣,歡迎閱讀我的《如何用iPad執行Python程式碼?》一文。)
請點選這個連結(t.cn/R3us4Ao),直接進入我們們的實驗環境。
你不需要在本地計算機安裝任何軟體包。只要有一個現代化瀏覽器(包括Google Chrome, Firefox, Safari和Microsoft Edge等)就可以了。全部的依賴軟體,我都已經為你準備好了。
開啟連結之後,你會看見這個頁面。
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/d68a2bb62dbaec59a93c8234efb3a9560a746d01ebac05a56cfb5aaf4c315634.png)
這個介面來自 Jupyter Lab。
圖中左側分欄,是工作目錄下的全部檔案。
右側開啟的,是我們們要使用的ipynb檔案。
根據我的講解,請你逐條執行,並仔細觀察執行結果。
本例中,我們主要會用到以下兩個新的軟體包。
首先是號稱“給人用”(for humans)的HTTP工具包requests。
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/189c11d11c05254f2bb2fd8d4ac868ed39c4f99664c7b29c876c1e7709d07f21.png)
這款工具,不僅符合人類的認知與使用習慣,而且對 Python 3 更加友好。作者 Kenneth Reitz 甚至在敦促所有的 Python 2 使用者,趕緊轉移到 Python 3 版本。
The use of Python 3 is highly preferred over Python 2. Consider upgrading your applications and infrastructure if you find yourself still using Python 2 in production today. If you are using Python 3, congratulations — you are indeed a person of excellent taste. —Kenneth Reitz
我們將用到的一款繪圖工具,叫做 plotnine 。
它實際上本不是 Python 平臺上的繪圖工具,而是從 R 平臺的 ggplot2 移植過來的。
要知道,此時 Python 平臺上,已經有了 matplotlib, seaborn, bokeh, plotly 等一系列優秀的繪圖軟體包。
那為什麼還要費時費力地,移植 ggplot2 過來呢?
因為 ggplot2 的作者,是大名鼎鼎的 R 語言大師級人物 Hadley Wickham 。
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/e55436156e992bfc6b121d5f7f14735a500c332176fb9a06523e27c2b621d4f2.png)
他創造 ggplot2,並非為 R 提供另一種繪圖工具,而是提供另一種繪圖方式。
ggplot2 完全遵守並且實現了 Leland Wilkinson 提出的“繪圖語法”(Grammar of Graphics),影像的繪製,從原本的部件拆分,變成了層級拆分。
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/fe607ed22b095738129901231887faffd268dc3d9cfb11fddf2b2002d51dcc27.png)
這樣一來,資料視覺化變得前所未有地簡單易學,且功能強大。
我會在後文的“程式碼”部分,用詳細的敘述,為你展示如何使用這兩個軟體包。
我建議你先完全按照教程跑一遍,執行出結果。
如果一切正常,再將其中的資料,替換為你自己感興趣的內容。
之後,嘗試開啟一個空白 ipynb 檔案,根據教程和文件,自己敲程式碼,並且嘗試做調整。
這樣會有助於你理解工作流程和工具使用方法。
下面我們來看程式碼。
程式碼
首先,讀入HTTP工具包requests。
import requests
複製程式碼
第二句裡面,有“Your AppCode here”字樣,請把它替換為你自己的AppCode,否則下面執行會報錯。
appcode = 'Your AppCode here'
複製程式碼
我們嘗試獲取麗江5月份的天氣資訊。
在API資訊頁面上,有城市和程式碼對應的表格。
位置比較隱蔽,在公司簡介的上方。
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/6b124131dc4745e591cdfbf92c27202d4bba51c7cb02551120f16fbda2e01ad4.png)
我把這個 Excel 文件的網址放在了這裡(http://t.cn/R3T7e39),你可以直接點選下載。
下載該 Excel 檔案後開啟,根據表格查詢,我們知道“101291401”是麗江的城市程式碼。
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/c0a55b034d0d0904ce78c77dd6d84d520e8711f60fcf9dac63809653fa95e402.png)
我們將其寫入areaid
變數。
日期我們選擇本文寫作的月份,即2018年5月。
areaid = "101291401"
month = "201805"
複製程式碼
下面我們就設定一下 API 介面呼叫相關的資訊。
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/e23865a64786db91b138c5917557a63854170e86cc8feade49b219b4038ac5ae.png)
根據API資訊頁面上的提示,我們的要訪問的網址為:https://ali-weather.showapi.com/weatherhistory
,需要輸入的兩個引數,就是剛才已經設定的areaid
和month
。
另外,我們需要驗證身份,證明自己已經付費了。
點選上圖中藍色的“API 簡單身份認證呼叫方法(APPCODE)”,你會看到以下示例頁面。
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/dcdf737e8759ea2a30fac03f32236b80a7e7b7c9e751b774163e284fcf8b7337.png)
看來我們需要在HTTP資料頭(header)中,加入 AppCode。
我們依次把這些資訊都寫好。
url = 'https://ali-weather.showapi.com/weatherhistory'
payload = {'areaid': areaid, 'month': month}
headers = {'Authorization': 'APPCODE {}'.format(appcode)}
複製程式碼
下面,我們就該用 requests 包來工作了。
requests 的語法非常簡潔,只需要指定4樣內容:
- 呼叫方法為“GET”
- 訪問地址 url
- url中需要附帶的引數,即 payload (包含
areaid
和month
的取值) - HTTP資料頭(header)資訊,即 AppCode
r = requests.get(url, params=payload, headers=headers)
複製程式碼
執行後,好像……什麼也沒有發生啊!
我們來檢視一下:
r
複製程式碼
Python 告訴我們:
<Response [200]>
複製程式碼
返回碼“200”的含義為訪問成功。
回顧一下,《如何用R和API免費獲取Web資料?》一文中,我們提到過:
以2開頭的狀態編碼是最好的結果,意味著一切順利;如果狀態值的開頭是數字4或者5,那就有問題了,你需要排查錯誤。
既然呼叫成功,我們看看 API 介面返回的具體資料內容吧。
呼叫返回值的 content 屬性:
r.content
複製程式碼
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/c34b11cd1c7792ebbabfe8933c6a29f45a3f573e72720af9da52400c24accbce.png)
這一螢幕,密密麻麻的。
其中許多字元,甚至都不能正常顯示。這可怎麼好?
沒關係,從 API 資訊頁上,我們得知返回的資料,是 JSON 格式。
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/5f9c470e7485e464fd42a7868ad86bda16bc0416426ffffbb5f2ae6821ff02e8.png)
那就好辦了,我們呼叫 Python 自帶的 json 包。
import json
複製程式碼
用 json 包的字串處理功能(loads)解析返回內容,結果存入 content_json
。
content_json = json.loads(r.content)
複製程式碼
看看 content_json
結果:
content_json
複製程式碼
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/422894d9b4a4575b21c8b24899fe78fa7303b2c7c18128502c1f1a1d36f8f292.png)
可以看到,返回的資訊很完整。而且剛剛無法正常顯示的中文,此時也都顯現了廬山真面目。
下一步很關鍵。
我們把真正關心的資料提取出來。
我們不需要返回結果中的錯誤碼等內容。
我們要的,是包含每一天天氣資訊的列表。
觀察發現,這一部分的資料,儲存在 'list' 中,而 'list' ,又儲存在 'showapi_res_body
' 裡面
所以,為選定列表,我們需要指定其中的路徑:
content_json['showapi_res_body']['list']
複製程式碼
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/d9fe51e30b4390bebd46252b4b45b62fa8719fc9c6bba41d70e459fee759d4b8.png)
冗餘資訊都被去掉了,只剩下我們想要的列表。
但是對著一個列表操作,不夠方便與靈活。
我們希望將列表轉換為資料框。這樣分析和視覺化就簡單多了。
大不了,我們還可以把資料框直接匯出為 Excel 檔案,扔到熟悉的 Excel 環境裡面,去繪製圖形。
讀入 Python 資料框工具 pandas 。
import pandas as pd
複製程式碼
我們讓 Pandas 將剛剛保留下來的列表,轉換為資料框,存入 df 。
df = pd.DataFrame(content_json['showapi_res_body']['list'])
複製程式碼
看看內容:
df
複製程式碼
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/ddd5324a1412d9ddc21a9409a71f4821e5ee4beed47ed72d641930aa4df18a62.png)
此時,資料顯示格式非常工整,各項資訊一目瞭然。
寫到這裡,你基本上搞懂了,如何讀取某個城市、某個月份的資料,並且整理到 Pandas 資料框中。
但是,我們要做分析,顯然不能侷限在單一月份與單一城市。
每次加入一組資料,如果都得從頭這樣做一遍,會很辛苦。而且語句多了,執行起來,難免顧此失彼,出現錯誤。
所以,我們需要把剛剛的程式碼語句整合起來,將其模組化,形成函式。
這樣,我們只需要在呼叫函式的時候,傳入不同的引數,例如不同的城市名、月份等資訊,就能獲得想要的結果了。
綜合上述語句,我們定義一個傳入城市和月份資訊,獲得資料框的完整函式。
def get_df(areaid, areaname_dict, month, appcode):
url = 'https://ali-weather.showapi.com/weatherhistory'
payload = {'areaid': areaid, 'month': month}
headers = {'Authorization': 'APPCODE {}'.format(appcode)}
r = requests.get(url, params=payload, headers=headers)
content_json = json.loads(r.content)
df = pd.DataFrame(content_json['showapi_res_body']['list'])
df['areaname'] = areaname_dict[areaid]
return df
複製程式碼
注意除了剛才用到的語句外,我們為函式增加了一個輸入引數,即areaname_dict
。
它是一個字典,每一項分別包括城市程式碼,和對應的城市名稱。
根據我們輸入的城市程式碼,函式就可以自動在結果資料框中新增一個列,註明對應的是哪個城市。
當我們獲取多個城市的資料時,某一行的資料說的是哪個城市,就可以一目瞭然。
反之,如果只給你看城市程式碼,你很快就會眼花繚亂,不知所云了。
但是,只有上面這一個函式,還是不夠高效。
畢竟我們可能需要查詢若干月、若干城市的資訊。如果每次都呼叫上面的函式,也夠累的。
所以,我們下面再編寫一個函式,幫我們自動處理這些髒活兒累活兒。
def get_dfs(areaname_dict, months, appcode):
dfs = []
for areaid in areaname_dict:
dfs_times = []
for month in months:
temp_df = get_df(areaid, areaname_dict, month, appcode)
dfs_times.append(temp_df)
area_df = pd.concat(dfs_times)
dfs.append(area_df)
return dfs
複製程式碼
說明一下,這個函式接受的輸入,包括城市程式碼-名稱字典、一系列的月份,以及我們的 AppCode。
它的處理方式,很簡單,就是個雙重迴圈。
外層迴圈負責遍歷所有要求查詢的城市,內層迴圈遍歷全部指定的時間範圍。
它返回的內容,是一個列表。
列表中的每一項,都分別是某個城市一段時間(可能包含若干個月)的天氣資訊資料框。
我們先用單一城市、單一月份來試試看。
還是2018年5月的麗江。
areaname_dict = {"101291401":"麗江"}
months = ["201805"]
複製程式碼
我們將上述資訊,傳入 get_dfs
函式。
dfs = get_dfs(areaname_dict, months, appcode)
複製程式碼
看看結果:
dfs
複製程式碼
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/3d5e80170bd149357c8530bb910c1fc5c33f686fa990fed76b28cb5c68461e78.png)
返回的是一個列表。
因為列表裡面只有一個城市,所以我們只讓它返回第一項即可。
dfs[0]
複製程式碼
這次顯示的,就是資料框了:
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/d139d58eff4eac53a8dc1af3cc77107963c500709f1767786b3592a95a60cfac.png)
測試通過,下面我們趁熱打鐵,把天津、上海、麗江2018年初至今所有資料都讀取出來。
先設定城市:
areaname_dict = {"101030100":"天津", "101020100":"上海", "101291401":"麗江"}
複製程式碼
再設定時間範圍:
months = ["201801", "201802", "201803", "201804", "201805"]
複製程式碼
我們們再次執行 get_dfs
函式。
dfs = get_dfs(areaname_dict, months, appcode)
複製程式碼
看看這次的結果:
dfs
複製程式碼
結果還是一個列表。
列表中的每一項,對應某個城市2018年年初到5月份本文寫作時,這一段時間範圍天氣資料。
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/f5516229a16f80b6be5b570478260d04411e2607f739c019e69b1dd19d84b70f.png)
假設我們要綜合分析幾個城市的天氣資訊,那麼就可以把這幾個資料框整合在一起。
用到的方法,是 Pandas 內建的 concat
函式。
它接收一個資料框列表,把其中每一個個資料框沿著縱軸(預設)連線在一起。
df = pd.concat(dfs)
複製程式碼
看看此時的總資料框效果:
df
複製程式碼
這是開頭部分:
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/562051fea9e587415f98ad755fe365710249bd3f0dc92f88a8a957c2bb69c34d.png)
這是結尾部分:
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/6d3ed96764c66e811752f792cdcc3bf88050fe8e5bd03ffdb76b93abc69de018.png)
3個城市,4個多月的資料都正確讀取和整合了。
下面我們嘗試做分析。
首先,我們得搞清楚資料框中的每一項,都是什麼格式:
df.dtypes
複製程式碼
aqi object
aqiInfo object
aqiLevel object
max_temperature object
min_temperature object
time object
weather object
wind_direction object
wind_power object
areaname object
dtype: object
複製程式碼
所有的列,全都是按照 object
處理的。
什麼叫 object
?
在這個語境裡,你可以將它理解為字串型別。
但是,我們們不能把它們都當成字串來處理啊。
例如日期,應該按照日期型別來看待,否則怎麼做時間序列視覺化?
AQI的取值,如果看作字串,那怎麼比較大小呢?
所以我們需要轉換一下資料型別。
先轉換日期列:
df.time = pd.to_datetime(df.time)
複製程式碼
再轉換 AQI 數值列:
df.aqi = pd.to_numeric(df.aqi)
複製程式碼
看看此時 df 的資料型別:
df.dtypes
複製程式碼
aqi int64
aqiInfo object
aqiLevel object
max_temperature object
min_temperature object
time datetime64[ns]
weather object
wind_direction object
wind_power object
areaname object
dtype: object
複製程式碼
這次就對了,日期和 AQI 都分別變成了我們需要的型別。其他資料,暫時保持原樣。
有的是因為本來就該是字串,例如城市名稱。
另一些,是因為我們暫時不會用到。
下面我們繪製一個簡單的時間序列對比圖形。
讀入繪圖工具包 plotnine 。
注意我們同時讀入了 date_breaks
,用來指定圖形繪製時,時間標註的間隔。
import matplotlib.pyplot as plt
%matplotlib inline
from plotnine import *
from mizani.breaks import date_breaks
複製程式碼
正式繪圖:
(ggplot(df, aes(x='time', y='aqi', color='factor(areaname)')) + geom_line() +
scale_x_datetime(breaks=date_breaks('2 weeks')) +
xlab('日期') +
theme_matplotlib() +
theme(axis_text_x=element_text(rotation=45, hjust=1)) +
theme(text=element_text(family='WenQuanYi Micro Hei'))
)
複製程式碼
我們指定橫軸為時間序列,縱軸為 AQI,用不同顏色的線來區分城市。
繪製時間的時候,以“2周”作為間隔週期,標註時間上的資料統計量資訊。
我們修改橫軸的標記為中文的“日期”。
因為時間顯示起來比較長,如果按照預設樣式,會堆疊在一起,不好看,所以我們讓它旋轉45度角,這樣避免重疊,一目瞭然。
為了讓圖中的中文正常顯示,我們需要指定中文字型,這裡我們選擇的是開源的“文泉驛微米黑”。
資料視覺化結果,如下圖所示。
![png](https://i.iter01.com/images/7c0be22c4b9610804b675c6524a98a292f5bf9935a3cdced7a9bd5b07f2397de.png)
怎麼樣,這張對比圖,繪製得還像模像樣吧?
從圖中,你可以分析出什麼結果呢?
反正我看完這張圖,很想去麗江。
小結
讀過本教程,希望你已經掌握了以下知識:
- 如何在 API 雲市場上,根據提示選購自己感興趣的產品;
- 如何獲取你的身份驗證資訊 AppCode ;
- 如何用最簡單的命令列 curl 方式,直接呼叫 API 介面,獲得結果資料;
- 如何使用 Python 3 和更人性化的 HTTP 工具包 requests 呼叫 API 獲得資料;
- 如何用 JSON 工具包解析處理獲得的字串資料;
- 如何用 Pandas 轉換 JSON 列表為資料框;
- 如何將測試通過後的簡單 Python 語句打包成函式,以反覆呼叫,提高效率;
- 如何用 plotnine (ggplot2的克隆)繪製時間序列折線圖,對比不同城市 AQI 歷史走勢;
- 如何在雲環境中執行本樣例,並且照葫蘆畫瓢,自行修改。
希望這份樣例程式碼,可以幫你建立信心,嘗試自己去搜集與嘗試 API 資料獲取,為自己的科研工作添磚加瓦。
如果你希望在本地,而非雲端執行本樣例,請使用這個連結(t.cn/R3usDi9)下載本文用到的全部原始碼和執行環境配置檔案(Pipenv)壓縮包。
如果你知道如何使用github,也歡迎用這個連結(t.cn/R3usEti)訪問對應的github repo,進行clone或者fork等操作。
![如何用 Python 和 API 收集與分析網路資料?](https://i.iter01.com/images/990df2399c125a1f24361d11f7491d13e599266d5b7260743fbd79f9fd9fdceb.png)
當然,要是能給我的repo加一顆星,就更好了。
討論
你之前嘗試過用 Python 和 API 獲取資料嗎?你使用了哪些更好用的軟體包進行資料獲取、處理、分析與視覺化呢?你還使用過哪些其他的資料產品市場?歡迎留言,把你的經驗和思考分享給大家,我們一起交流討論。
喜歡請點贊。還可以微信關注和置頂我的公眾號“玉樹芝蘭”(nkwangshuyi)。
如果你對資料科學感興趣,不妨閱讀我的系列教程索引貼《如何高效入門資料科學?》,裡面還有更多的有趣問題及解法。