如何用Python科學分析天氣——城市歷年氣象報告
?? 截至本文發布,受厄爾尼諾影響,整個長沙城已經在雨水裡泡了差不多兩個月:
剛好最近又一直在用python做數據分析方向的研究,本著科(chi)學(bao)分(cheng)析(zhe)的態度,決定做一期關於長沙歷年氣象的分析報告。
本文簡單記錄了整個工作流程,以此方便其他地區的朋友參照本範例科學分析。
【數據篇】
首先當然是去找數據源,歷史氣象數據不是什麼機密數據,在國家氣象信息中心就可以找到:
中國地面國際交換站氣候資料日值數據集(V3.0)
數據還是比較全的,從建國後開始至今接近70年的數據。
看來我國的科學數據信息還是比較開放的。
但是,當你要批量下載數據的時候…
。。。。。。
也就是說,一次檢索不能大於2個月,那麼下載70年的數據需要設置這個頁面420次,再加上生成和下載,手速快不吃不喝連續作業也大概需要花掉20個小時的時間,所以…
理論上我們可以用python寫一個爬蟲把數據爬下來,但是不到最後需要自己造輪子的時候,盡量還是尋找更簡單的方法。
地面國際交換站之所以叫國際交換站就是因為這個數據是和其他國家共享的,我國下載受限的話,理論上在數據更公開的其他國家(此處手動@USA)可以嘗試搜索一下。
NOAA(美國國家海洋和大氣管理局)應該有我們需要的數據,首先官網進去找到數據中心的地址,為了節約大家的搜索時間這裡直接貼出資料庫的入口地址
(https://www.ncdc.noaa.gov/data-access/land-based-station-data/land-based-datasets)
https://www.ncdc.noaa.gov/data-access/land-based-station-data/land-based-dataset
我們要找的數據在GHCN(全球歷史氣象學網路),看描述感覺很硬核,記錄了自測量器誕生以來地球的所有歷史氣象數據,最早可追溯到了17世紀。
我們當然不需要這麼多,能獲取到目標地區氣象站的幾十年完整數據即可。
之後通過給出的鏈接進入FTP,這裡可以下載全部的數據,沒有任何地區和許可權限制,只要連接了網路就可以下載。
不得不說一個國家的科技進步水平和其科技資源的開放程度是成正比的。
點擊進入FTP,然後:
通常進一個FTP資料庫,第一時間有點不知道從何入手是很正常的,基本上我會把root下的readme.txt看一遍,一般心裡就大概有數了。
ghcnd-stations.txt記錄了所有氣象站的編碼信息,在之後的查詢中我們需要用編碼來檢索數據。
?
搜索目標地點CHANGSHA(長沙),看到有兩個氣象站,編號57687的那個之前在中國國家氣象信息中心查到過,通過經緯度和地圖可以發現它架設在嶽麓區。編號57687這個氣象站從1970年1月開始監測,但是不存在編號57679的氣象站,我們先不管它,可以把這兩個站點的數據都下載之後再看。
ghcnd-inventory.txt記錄了數據詳細清單,通過搜索之前查詢到的長沙氣象站的編碼,可以看到氣象站57687的數據清單,平均氣溫(TAVG)記錄從1944年就開始了,降雨量(PRCP)從1987年開始。而氣象站57679的數據從1951年開始就非常統一和完整,只是在十年前停止了記錄,可能是關閉了。所以之後把這兩個氣象站的數據合併一下,基本就可以完整反映出長沙地區1951-2019的氣象情況。
而我們需要的數據本體在all目錄下:
分別下載CHM00057679.dly和CHM00057687.dly這兩個氣象站的全部數據。
最後我們用UE打開文件,可以看到,記錄從1951年1月開始,其中包含了最高氣溫,最低氣溫,平均氣溫(0.1攝氏度)及降雨量(0.1mm)。這裡的s是列分隔符,每一列表示當月中某一天的數據值。
?
其實還是想再多拿到一些數據,比如相對濕度,降雪,氣壓等。不過有了氣溫和降水數據基本也可以統計出長沙歷史的氣象概況了。如果有朋友能夠拿到更豐富的氣象數據,也歡迎提供一下。
關於數據獲取的內容就先說到這裡,肯定還有能獲取更全面數據的方法,以後有新的發現會另外再開篇拓展。
【編碼篇】
拿到數據以後,就可以開始用Python編寫代碼開始分析了:
對代碼不感興趣的同學可以直接跳過本節直接看分析報告。
首先這個demo用到的庫如下:
Pandas用來做數據整理,Matplotlib用來繪圖,Math是數學基本庫,以及Re正則庫,用來對原始格式的數據進行分割篩選。
Step1:數據讀取及整理
從老美那拿到的數據結構雖然已經比較清晰了,但還是不能拿來直接用,我們需要把逐月數據轉換成逐天數據,然後保存到DataFrame里。
首先定義四個空的DataFrame,注釋已標。
之後對dly文件進行逐行(逐月)讀取,將單行進行字元串的分割,取出時間以及每個單日數據。
這裡有兩個循環,一個循環是dly文本文件的逐行讀取,另一個循環是每一行中每一天的列數值讀取和創建一行日數據df。獲取並組合成新的日數據df之後,就可以添加進之前創建的指定類型的空DataFrame中。這裡只截圖了PRCP(降雨統計)的部分,其他部分同理。
關於數據顯示時的顏色值,這裡用了HSV顏色模型的思路,通過改變H(色相)值,來實現通過顏色表示數據大小的效果。實際也可以不需要,只是為了顯示時更好看一些而已。這一塊不是重點,可以略過。
Step2:散點圖繪製
依舊以PRCP為例:
繪製圖表可以調用Maltplotlib.pyplot庫下的各個方法。其中繪製散點圖的方法為scatter(),參數中x軸填入日索引(當年的第幾天)集合,y軸填入當日降雨量集合,s表示點的大小,這裡設置為40,c表示顏色,可以使用固定字元串或者之前設置匹配數值的顏色集合。marker表示點的形狀,alpha表示點的透明度。
運行之後的效果是這樣的:
每一個點表示70年中某一天的值,通過這張圖就可以大概看出歷年降雨量和日期的關係,以及分布情況。
平均氣溫TAVG也有一張散點圖,用來展示歷年氣溫分布和日期的關係,和PRCP的顯示方法相同,因此這裡就不再重複說明。
Step3:線性圖繪製
在本步驟中我們將用線性圖來展示數據在逐年中的變化情況。需要統計的數據有:單個年份中有降雨的天數,炎熱(TAVG > 30°C)天數以及寒冷(TAVG < 10°C)
統計數據的代碼如下:
通過DataFrame的groupby()方法來將逐日數據按照年份進行分組,之後再使用count()方法對分組進行計數統計,產生的數據集即為我們需要的年統計數據。
有了數據之後,繪製線性圖的方法也很簡單:
在同一張畫布上調用三次plot()方法,分別繪製年降雨天數、年高溫天數、年低溫天數這三個數據集的逐年線性變化曲線:
Step4:柱狀圖繪製
之後我們還需要再統計兩類直觀數據,即歷史上同一天的事件發生頻率(如某一天的歷史降雨頻率)以及所有年份中事件連續發生的最值和時間段(如每一年連續降雨最長天數以及發生的日期)。
首先是事件發生頻率圖,以降雨為例:
運行結果如下:
事件發生頻率還可用於統計歷史年份某一天嚴寒或者酷暑的概率,數據集的篩選方式不同但原理相同。
接下來就是我們最後的一類數據分析了,即事件連續發生天數逐年最值以及發生日期。這裡仍舊分析降雨數據。我們需要計算出每一年連續下雨最長的天數以及從什麼時候開始到什麼時候結束。
代碼如下:
注意到這裡用的是plt.barh()方法,即橫向柱狀圖繪製,同時添加了left=?標籤,用於對柱狀圖塊進行位移(位移用來表示從哪一天開始,不設置的話默認都是從x=0開始)。
另外自定義了一個計算連續天數的函數,稍微複雜一些所以不適合用lambda表達式來直接寫:
基本思路就是循環結果集中的所有數據,遇到連續索引的日期就進行累加,當累加超過之前保存過的最大值時就覆蓋掉之前的記錄,所有結果循環完畢之後,最後留下的記錄就是最大值記錄。
最後的效果如圖:
每一個柱狀圖塊的長度表示了每一年的降雨最大天數,圖塊的位置表示了連續降雨的起始和結束時間。
編碼寫到這裡,最核心的幾個步驟就結束了,剩下的就是一些同類型的拓展統計需求,使用上述的數據集和方法基本上都能夠實現,這裡就不再拓展編碼說明了。
接下來就是最後的一個步驟——數據分析。
【分析篇】
首先要感謝能夠看到這裡或直接跳到這裡的同學,可能大家稍微有興趣的也就是這一部分了。
基於上一篇的程序運算,我們一共生成了8張圖:
這是一張散點圖,每一個點表示70年中某一天的平均氣溫,直接呈現了氣溫與年單位時間的對應關係,可以看到歷史同比的平均氣溫分布跨度都比較大,不同年份同比最大甚至出現了20C°的差異。
但綜合來看還是比較直觀的,長沙從11月中旬開始進入低溫模式( TAVG<10C°),到次年的2月初開始逐步回溫,直到3月中旬徹底結束長達4個月的寒冷天氣。
也不排除有少數非常暖的年份,在2月初就早早迎來了春天。但醒醒吧,那只是少數。
總之,長沙的冬天真的就是一場噩夢。
而溫度扮演的並不是最主要的角色,濕度才是噩夢的主角,這在後面會重點說明。
而長沙的炎熱天氣對比之下就不是很長了,綜合來看,從6月底氣溫逐步上升到30C°左右,經過7-8這兩個月的盛夏之後,在9月初氣溫開始逐步回落。
之前有小夥伴問我什麼時候來長沙玩比較合適,那麼就氣溫來說,上圖中出現綠色比較多的時間是比較宜居的。即3月中旬到5月中旬,9月中旬到11月中旬,合計是4個月的時間。
那剩下8個月在幹嘛呢?剩下8個月都在一邊哭唧唧的和天氣做鬥爭,一邊在等待這4個月。
接下來就氣溫情況還有一張圖作為補充:
從圖中可以看到夏季連續高溫的天氣並不長,只是在2013年7月出現了一次連續一個半月的高溫天氣。
而連續的低溫天氣相對就比較漫長了,甚至在2012年出現了一次長達兩個半月的超長低溫天氣,這還沒有算上2011年入冬之後的連續低溫。
所以抱怨長沙的夏天有多熱的小夥伴,還是多思考一下接下來的冬天有多難熬吧…
說完溫度接下來就要說最可怕的降雨情況了。冬天其實並不可怕,可怕的是冬天沒有太陽還下著雨。
首先不要被這張圖嚇到,一片藍色不代表一年365天都在下雨,而是表示這70年里,幾月幾號這一天有下過雨。
可以看到歷史上365天都曾有過下雨記錄,肯定是不存在不下雨的某一個幸運日的。雨量隨著夏季的到來呈上升趨勢,在6月到達頂峰,接下來炎熱的7月和8月降雨量開始相對減少。而其他時間也是有概率降雨的,這一點亞熱帶季風氣候的城市都是如此,並不會有太大的區別。
重點是後面的兩張圖:
這兩張圖很直觀的展示了,歷史同比日單位的降雨頻率……
通俗點說就是統計了這70年以來,某月某日出現過降雨的次數,以此來計算出這一天會下雨的概率。
從圖4可以看到長沙常年降雨頻率都在30%以上,從1月份開始上升到了40%,2月中下旬開始徹底爆發,超過了50%、60%,一直到7月盛夏才有所下降。
其實下雨就下吧,這也不是重點,重點是圖5——出現降水同時氣溫又低於10C°的頻率統計。可以看到,1、2兩月這樣的天氣出現的頻率均值達到了45%以上,所以這也就是最近這兩個月這麼難熬的原因了:
空氣濕度長期在80%以上,空調加熱一屋子的空氣要比北方難太多了,即便是學北方用了暖氣片也只能加熱周圍一圈的局部溫度,靠在邊上身體一邊是熱的一邊卻是涼的...
出門到外面,空氣中無限接近0度又不結冰的水分子加速了體溫的熱傳導,再厚實的棉襖也挨不住水分子的滲透,風再一吹加速一下熱對流,那種絕望的感受只有長江以南一帶的小夥伴才會懂。
而歷史上連續下雨的天數極值可以參考下圖:
可以看到並不是每年都有超長的時間一直連續下雨,大部分都會在10天以內結束,但是有可能出一天太陽接著下十天雨這樣的情況,為了調查到底,於是有了圖7:
結果,當然是很絕望。
圖中每一個藍色的點都表示歷史上當天有降雨記錄,空白區域則表示當天沒有降雨記錄。綜合來看每年接近一半的時間都在下雨,冬末至夏初的降雨尤為頻繁。
最後一張圖,統計了長沙歷史的降雨及高溫 (大於30 C°)和低溫(小於10 C°)的各年天數:
可以看到,橙色、藍色、綠色線條分別表示高溫、低溫和降雨天數。一年有接近一半天數在下雨,接近三分之一的天氣低溫寒冷,這些數據已經非常充分的說明了長沙是一個濕冷多過炎熱的城市。
而長沙最近的雨水,簡直是哭成了淚人。
以上的8張圖,從各個時間維度和量化標準上對長沙歷年的氣象情況做了一個大致的分析。70年的數據,幾乎覆蓋了許多人窮極一生所能經歷的種種氣象。
雖然反覆無常,最近又一直是陰雨綿綿,但也還是起起落落會有一定的規律可循。而生活不就是這樣嗎。
最後,再奉上統計出來的長沙歷史的氣象極值:
歷史最高氣溫:1953年8月13日,40.6 C°
歷史最低氣溫:1972年2月9日,-11.3 C°
歷史單日最大降水量:1997年6月7日,249.5mm
歷史連續降雨天數記錄:2018年12月25日至2019年1月21日,連續降雨28天
本文關於數據的獲取及分析的內容到此就全部結束,若有紕漏歡迎指正。如果有小夥伴想分析其他地區的氣象情況,也歡迎留言或私信我。
本文涉及的所有代碼已開源並上傳至GitHub,歡迎感興趣的小夥伴fork,一起繼續優化開發。
GitHub地址:
BeiTown/WeatherAnalysisBeiTown
2019-03-02????
推薦閱讀: