一、實驗介紹
本實驗將對意大利北部沿海地區的氣象數據進行分析與可視化。我們在實驗過程中先會運用 Python 中matplotlib庫的對數據進行圖表化處理,然后調用
1.1 課程來源
本課程基於
為了保證可以在實驗樓環境中完成本次實驗,我們在原書內容基礎上補充了一系列的實驗指導,比如實驗截圖,代碼注釋,幫助您更好得實戰。
如果您對於實驗有疑惑或者建議可以隨時在討論區中提問,與同學們一起探討。
1.2 實驗知識點
-
matplotlib 庫畫出圖像
-
scikit-learn 庫對數據進行回歸分析
-
numpy 庫對數據進行切片
1.3 實驗環境
-
python2.7
-
spyder
-
Xfce終端
1.4 適合人群
本課程難度為中等,適合具有Python基礎的用戶,如果對 matplotlib 模塊有了解會更快的上手。
1.5 代碼獲取
你可以通過下面命令將代碼下載到實驗樓環境中,作為參照對比進行學習。
$ wget http://labfile.oss.aliyuncs.com/courses/780/SourceCode.zip
$ wget http://labfile.oss.aliyuncs.com/courses/780/WeatherData.zip
本實驗在交互式的環境當中完成,代碼不能直接在命令行中運行(因為要畫圖)。如果想要看效果的同學可以把 SourceCode.zip 和 WeatherData.zip 解壓,然后打開桌面上的 spyder, 在Ipython console的交互式環境中進入 WeatherData 所在路徑,然后把代碼黏貼到 console 當中去。具體方式請看如下的 gif 圖。

在這里還是要呼吁大家不要簡單的復制粘貼代碼,還是要依照本實驗的教程自己一步步得實現。
二、實驗原理
氣象數據是在網上很容易找到的一類數據。很多網站都提供以往的氣壓、氣溫、濕度和降雨量等氣象數據。只需指定位置和日期,就能獲取一個氣象數據文件。這些測量數據是由氣象站收集的。氣象數據這類數據源涵蓋的信息范圍較廣。數據分析的目的是把原始數據轉化為信息,再把信息轉化為知識,因此拿氣象數據作為數據分析的對象來講解數據分析全過程再合適不過。
2.1 待檢驗的假設:靠海對氣候的影響
寫作本章時,雖正值夏初,卻已酷熱難耐,住在大城市的人感受更為強烈。於是周末很多人到山村或海濱城市去游玩,放松一下身心,遠離內陸城市的悶熱天氣。我常常想,靠海對氣候有什么影響?這個問題可以作為數據分析的一個不錯的出發點。我不想把本章寫成科學類讀物,只是想借助這樣一種方式,讓數據分析愛好者能夠把所學用於實踐,解決“海洋對一個地區的氣候有何影響”這個問題。
研究系統:亞得里亞海和波河流域
既然已定義好問題,就需要尋找適合研究數據的系統,提供適合回答這個問題的環境。首先,需要找到一片海域供你研究。我住在意大利,可選擇的海有很多,因為意大利是一個被海洋包圍的半島國家。為什么要把自己的選擇局限在意大利呢?因為我們所研究的問題剛好和意大利人的一種典行為相關,也就是夏天我們喜歡躲在海邊,以躲避內陸的酷熱。我不知道在其他國家這種行為是否也很普遍,因此我只把自己熟悉的意大利作為一個系統進行研究。但是你可能會考慮研究意大利的哪個地區呢?上面說過,意大利是半島國家,找到可研究的海域不是問題,但是如何衡量海洋對其遠近不同的地方的影響?這就引出了一個大問題。意大利其實多山地,離海差不多遠,可以彼此作為參照的內陸區域較少。為了衡量海洋對氣候的影響,我排除了山地,因為山地也許會引入其他很多因素,比如海拔。
意大利波河流域這塊區域就很適合研究海洋對氣候的影響。這一片平原東起亞得里亞海,向內陸延伸數百公里(見圖9-1)。它周邊雖不乏群山環繞,但由於它很寬廣,削弱了群山的影響。此外,該區域城鎮密集,也便於選取一組離海遠近不同的城市。我們所選的幾個城市,兩個城市間的最大距離約為400公里。
第一步,選10個城市作為參照組。選擇城市時,注意它們要能代表整個平原地區(見圖9-2)。
如圖9-2所示,我們選取了10個城市。隨后將分析它們的天氣數據,其中5個城市在距海100公里范圍內,其余5個距海100~400公里。
選作樣本的城市列表如下:
-
Ferrara(費拉拉)
-
Torino(都靈)
-
Mantova(曼托瓦)
-
Milano(米蘭)
-
Ravenna(拉文納)
-
Asti(阿斯蒂)
-
Bologna(博洛尼亞)
-
Piacenza(皮亞琴察)
-
Cesena(切塞納)
-
Faenza(法恩莎)
現在,我們需要弄清楚這些城市離海有多遠。方法有多種。這里使用
有了計算兩城市間距離這樣的服務,我們就可以計算每個城市與海之間的距離。你可以選擇 海濱城市Comacchio作為基點,計算其他城市與它之間的距離(見圖9-2)。使用上述服務計算完 所有距離后,得到的結果如表9-1所示。
三、開發准備
定義好要研究的系統之后,我們就需要創建數據源,以獲取研究所需的數據。上網瀏覽一番,你就會發現很多網站都提供世界各地的氣象數據,其中就有Open Weather Map,它的網址是
該網站提供以下功能:在請求的URL中指定城市,即可獲取該城市的氣象數據。我們已經准備好了數據,不需要大家再去調用該網站的 API。
啟動桌面上的spyder。如果您發現您桌面上沒有spyder,請在該實驗中重新開一個實驗環境(實驗樓為不同的實驗創建不同的實驗環境):
我們首先來獲取我們的數據文件。打開 Xfce 終端
$ cd Code
$ mkdir WeatherAnalysis
$ cd WeatherAnalysis
$ wget http://labfile.oss.aliyuncs.com/courses/780/WeatherData.zip
$ unzip WeatherData.zip
這時候應該能夠再 WeatherData 中間看到 10 個城市的天氣數據文件(以 .csv 結尾)
雙擊打開 spyder ,在 Ipython Console 中進入我們的目標目錄
cd Code
cd WeatherAnalysis
cd WeatherData
我們在實驗里只需要用到 Ipython Console 所以別的不相關的窗口可以關閉。
import numpy as np
import pandas as pd
import datetime
如果你想用本章的數據,需要加載寫作本章時保存的10個CSV文件。
df_ferrara = pd.read_csv('ferrara_270615.csv')
df_milano = pd.read_csv('milano_270615.csv')
df_mantova = pd.read_csv('mantova_270615.csv')
df_ravenna = pd.read_csv('ravenna_270615.csv')
df_torino = pd.read_csv('torino_270615.csv')
df_asti = pd.read_csv('asti_270615.csv')
df_bologna = pd.read_csv('bologna_270615.csv')
df_piacenza = pd.read_csv('piacenza_270615.csv')
df_cesena = pd.read_csv('cesena_270615.csv')
df_faenza = pd.read_csv('faenza_270615.csv')
我們把這些數據讀入內存,完成了實驗准備的部分。
四、項目文件結構
Pic9-* 代表的是每一張分析圖所使用的代碼。
WeatherData 是我們的數據。
五、實驗步驟
從數據可視化入手分析收集到的數據是常見的做法。前面講過,matplotlib庫提供一系列圖表生成工具,能夠以可視化形式表示數據。數據可視化在數據分析階段非常有助於發現研究系統的一些特點。
導入以下必要的庫:
%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from dateutil import parser
5.1 溫度數據分析
舉例來說,非常簡單的分析方法是先分析一天中氣溫的變化趨勢。我們以城市米蘭為例。
# 讀取米蘭的城市氣象數據
df_milano = pd.read_csv('milano_270615.csv')
# 取出我們要分析的溫度和日期數據
y1 = df_milano['temp']
x1 = df_milano['day']
# 把日期數據轉換成 datetime 的格式
day_milano = [parser.parse(x) for x in x1]
# 調用 subplot 函數, fig 是圖像對象,ax 是坐標軸對象
fig, ax = plt.subplots()
# 調整x軸坐標刻度,使其旋轉70度,方便查看
plt.xticks(rotation=70)
# 設定時間的格式
hours = mdates.DateFormatter('%H:%M')
# 設定X軸顯示的格式
ax.xaxis.set_major_formatter(hours)
# 畫出圖像,day_milano是X軸數據,y1是Y軸數據,‘r’代表的是'red' 紅色
ax.plot(day_milano ,y1, 'r')
# 顯示圖像
fig
執行上述代碼,將得到如圖9-8所示的圖像。由圖可見,氣溫走勢接近正弦曲線,從早上開始氣溫逐漸升高,最高溫出現在下午兩點到六點之間,隨后氣溫逐漸下降,在第二天早上六點時達到最低值。
我們進行數據分析的目的是嘗試解釋是否能夠評估海洋是怎樣影響氣溫的,以及是否能夠影響氣溫趨勢,因此我們同時來看幾個不同城市的氣溫趨勢。這是檢驗分析方向是否正確的唯一方式。因此,我們選擇三個離海最近以及三個離海最遠的城市。
# 讀取數據文件(之前沒讀取數據的同學,這里一定要讀取啦)
df_ravenna = pd.read_csv('ravenna_270615.csv')
df_faenza = pd.read_csv('faenza_270615.csv')
df_cesena = pd.read_csv('cesena_270615.csv')
df_asti = pd.read_csv('asti_270615.csv')
df_torino = pd.read_csv('torino_270615.csv')
df_milano = pd.read_csv('milano_270615.csv')
# 讀取溫度和日期數據
y1 = df_ravenna['temp']
x1 = df_ravenna['day']
y2 = df_faenza['temp']
x2 = df_faenza['day']
y3 = df_cesena['temp']
x3 = df_cesena['day']
y4 = df_milano['temp']
x4 = df_milano['day']
y5 = df_asti['temp']
x5 = df_asti['day']
y6 = df_torino['temp']
x6 = df_torino['day']
# 把日期從 string 類型轉化為標准的 datetime 類型
day_ravenna = [parser.parse(x) for x in x1]
day_faenza = [parser.parse(x) for x in x2]
day_cesena = [parser.parse(x) for x in x3]
dat_milano = [parser.parse(x) for x in x4]
day_asti = [parser.parse(x) for x in x5]
day_torino = [parser.parse(x) for x in x6]
# 調用 subplots() 函數,重新定義 fig, ax 變量
fig, ax = plt.subplots()
plt.xticks(rotation=70)
hours = mdates.DateFormatter('%H:%M')
ax.xaxis.set_major_formatter(hours)
#這里需要畫出三根線,所以需要三組參數, 'g'代表'green'
ax.plot(day_ravenna,y1,'r',day_faenza,y2,'r',day_cesena,y3,'r')
ax.plot(dat_milano,y4,'g',day_asti,y5,'g',day_torino,y6,'g')
fig
上述代碼將生成如圖9-9所示的圖表。離海最近的三個城市的氣溫曲線使用紅色,而離海最遠的三個城市的曲線使用綠色。
如圖9-9所示,結果看起來不錯。離海最近的三個城市的最高氣溫比離海最遠的三個城市低不少,而最低氣溫看起來差別較小。
我們可以沿着這個方向做深入研究,收集10個城市的最高溫和最低溫,用線性圖表示氣溫最值點和離海遠近之間的關系。
# dist 是一個裝城市距離海邊距離的列表
dist = [df_ravenna['dist'][0],
df_cesena['dist'][0],
df_faenza['dist'][0],
df_ferrara['dist'][0],
df_bologna['dist'][0],
df_mantova['dist'][0],
df_piacenza['dist'][0],
df_milano['dist'][0],
df_asti['dist'][0],
df_torino['dist'][0]
]
# temp_max 是一個存放每個城市最高溫度的列表
temp_max = [df_ravenna['temp'].max(),
df_cesena['temp'].max(),
df_faenza['temp'].max(),
df_ferrara['temp'].max(),
df_bologna['temp'].max(),
df_mantova['temp'].max(),
df_piacenza['temp'].max(),
df_milano['temp'].max(),
df_asti['temp'].max(),
df_torino['temp'].max()
]
# temp_min 是一個存放每個城市最低溫度的列表
temp_min = [df_ravenna['temp'].min(),
df_cesena['temp'].min(),
df_faenza['temp'].min(),
df_ferrara['temp'].min(),
df_bologna['temp'].min(),
df_mantova['temp'].min(),
df_piacenza['temp'].min(),
df_milano['temp'].min(),
df_asti['temp'].min(),
df_torino['temp'].min()
]
先把最高溫畫出來。
fig, ax = plt.subplots()
ax.plot(dist,temp_max,'ro')
fig
結果如圖9-10所示。
如圖9-10所示,現在你可以證實,海洋對氣象數據具有一定程度的影響這個假設是正確的(至 少這一天如此)。
進一步觀察上圖,你會發現海洋的影響衰減得很快,離海60~70公里開外,氣溫就已攀升到 高位。
用線性回歸算法得到兩條直線,分別表示兩種不同的氣溫趨勢,這樣做很有趣。我們可以使 用scikit- learn庫的SVR方法。(注意:這段代碼會跑比較久的時間)
from sklearn.svm import SVR
# dist1是靠近海的城市集合,dist2是遠離海洋的城市集合
dist1 = dist[0:5]
dist2 = dist[5:10]
# 改變列表的結構,dist1現在是5個列表的集合
# 之后我們會看到 numpy 中 reshape() 函數也有同樣的作用
dist1 = [[x] for x in dist1]
dist2 = [[x] for x in dist2]
# temp_max1 是 dist1 中城市的對應最高溫度
temp_max1 = temp_max[0:5]
# temp_max2 是 dist2 中城市的對應最高溫度
temp_max2 = temp_max[5:10]
# 我們調用SVR函數,在參數中規定了使用線性的擬合函數
# 並且把 C 設為1000來盡量擬合數據(因為不需要精確預測不用擔心過擬合)
svr_lin1 = SVR(kernel='linear', C=1e3)
svr_lin2 = SVR(kernel='linear', C=1e3)
# 加入數據,進行擬合(這一步可能會跑很久,大概10多分鍾,休息一下:) )
svr_lin1.fit(dist1, temp_max1)
svr_lin2.fit(dist2, temp_max2)
# 關於 reshape 函數請看代碼后面的詳細討論
xp1 = np.arange(10,100,10).reshape((9,1))
xp2 = np.arange(50,400,50).reshape((7,1))
yp1 = svr_lin1.predict(xp1)
yp2 = svr_lin2.predict(xp2)
# 限制了 x 軸的取值范圍
ax.set_xlim(0,400)
# 畫出圖像
ax.plot(xp1, yp1, c='b', label='Strong sea effect')
ax.plot(xp2, yp2, c='g', label='Light sea effect')
fig
這里 np.arange(10,100,10) 會返回 [10, 20, 30,..., 90],如果把列表看成是一個矩陣,那么這個矩陣是 1 9 的。這里 reshape((9,1)) 函數就會把該列表變為 1 9 的, [[10], [20], ..., [90]]。這么做的原因是因為 predict() 函數的只能接受一個 N 1 的列表,返回一個 1 N 的列表。
上述代碼將生成如圖9-11所示的圖像。
如上所見,離海60公里以內,氣溫上升速度很快,從28度陡升至31度,隨后增速漸趨緩和(如果還繼續增長的話),更長的距離才會有小幅上升。這兩種趨勢可分別用兩條直線來表示,直線的表達式為:
x = ax + b
其中a為斜率,b為截距。
print svr_lin1.coef_ #斜率
print svr_lin1.intercept_ # 截距
print svr_lin2.coef_
print svr_lin2.intercept_
[[0.04794118]]
[ 27.65617647]
[[0.00401274]]
[ 29.98745223]
你可能會考慮將這兩條直線的交點作為受海洋影響和不受海洋影響的區域的分界點,或者至少是海洋影響較弱的分界點。
from scipy.optimize import fsolve
# 定義了第一條擬合直線
def line1(x):
a1 = svr_lin1.coef_[0][0]
b1 = svr_lin1.intercept_[0]
return a1*x + b1
# 定義了第二條擬合直線
def line2(x):
a2 = svr_lin2.coef_[0][0]
b2 = svr_lin2.intercept_[0]
return a2*x + b2
# 定義了找到兩條直線的交點的 x 坐標的函數
def findIntersection(fun1,fun2,x0):
return fsolve(lambda x : fun1(x) - fun2(x),x0)
result = findIntersection(line1,line2,0.0)
print "[x,y] = [ %d , %d ]" % (result,line1(result))
# x = [0,10,20, ..., 300]
x = np.linspace(0,300,31)
plt.plot(x,line1(x),x,line2(x),result,line1(result),'ro')
執行上述代碼,將得到交點的坐標
[x,y] = [ 53, 30 ]
並得到如圖9-12所示的圖表。
因此,你可以說海洋對氣溫產生影響的平均距離(該天的情況)為53公里。
現在,我們可以轉而分析最低氣溫。
# axis 函數規定了 x 軸和 y 軸的取值范圍
plt.axis((0,400,15,25))
plt.plot(dist,temp_min,'bo')
在這個例子中,很明顯夜間或早上6點左右的最低溫與海洋無關。如果沒記錯的話,小時候老師教給大家的是海洋能夠緩和低溫,或者說夜間海洋釋放白天吸收的熱量。但是從我們得到情況來看並非如此。我們剛使用的是意大利夏天的氣溫數據,而驗證該假設在冬天或其他地方是否也成立,將會非常有趣。
5.2 濕度數據分析
10個DataFrame對象中還包含濕度這個氣象數據。因此,你也可以考察當天三個近海城市和 三個內陸城市的濕度趨勢。
# 讀取濕度數據
y1 = df_ravenna['humidity']
x1 = df_ravenna['day']
y2 = df_faenza['humidity']
x2 = df_faenza['day']
y3 = df_cesena['humidity']
x3 = df_cesena['day']
y4 = df_milano['humidity']
x4 = df_milano['day']
y5 = df_asti['humidity']
x5 = df_asti['day']
y6 = df_torino['humidity']
x6 = df_torino['day']
# 重新定義 fig 和 ax 變量
fig, ax = plt.subplots()
plt.xticks(rotation=70)
# 把時間從 string 類型轉化為標准的 datetime 類型
day_ravenna = [parser.parse(x) for x in x1]
day_faenza = [parser.parse(x) for x in x2]
day_cesena = [parser.parse(x) for x in x3]
day_milano = [parser.parse(x) for x in x4]
day_asti = [parser.parse(x) for x in x5]
day_torino = [parser.parse(x) for x in x6]
# 規定時間的表示方式
hours = mdates.DateFormatter('%H:%M')
ax.xaxis.set_major_formatter(hours)
#表示在圖上
ax.plot(day_ravenna,y1,'r',day_faenza,y2,'r',day_cesena,y3,'r')
ax.plot(day_milano,y4,'g',day_asti,y5,'g',day_torino,y6,'g')
fig
上述代碼將生成如圖9-14所示的圖表。
乍看上去好像近海城市的濕度要大於內陸城市,全天濕度差距在20%左右。我們再來看一下濕度的極值和離海遠近之間的關系,是否跟我們的第一印象相符。
# 獲取最大濕度數據
hum_max = [df_ravenna['humidity'].max(),
df_cesena['humidity'].max(),
df_faenza['humidity'].max(),
df_ferrara['humidity'].max(),
df_bologna['humidity'].max(),
df_mantova['humidity'].max(),
df_piacenza['humidity'].max(),
df_milano['humidity'].max(),
df_asti['humidity'].max(),
df_torino['humidity'].max()
]
plt.plot(dist,hum_max,'bo')
我們把10個城市的最大濕度與離海遠近之間的關系做成圖表,請見圖9-15。
# 獲取最小濕度
hum_min = [df_ravenna['humidity'].min(),
df_cesena['humidity'].min(),
df_faenza['humidity'].min(),
df_ferrara['humidity'].min(),
df_bologna['humidity'].min(),
df_mantova['humidity'].min(),
df_piacenza['humidity'].min(),
df_milano['humidity'].min(),
df_asti['humidity'].min(),
df_torino['humidity'].min()
]
plt.plot(dist,hum_min,'bo')
再來把10個城市的最小濕度與離海遠近之間的關系做成圖表,請見圖9-16。
由圖9-15和圖9-16可以確定,近海城市無論是最大還是最小濕度都要高於內陸城市。然而在 我看來,我們還不能說濕度和距離之間存在線性關系或者其他能用曲線表示的關系。我們采集的 數據點數量(10)太少,不足以描述這類趨勢。
5.3 風向頻率玫瑰圖
在我們采集的每個城市的氣象數據中,下面兩個與風有關:
-
風力(風向)
-
風速
分析存放每個城市氣象數據的DataFrame就會發現,風速不僅跟一天的時間段相關聯,還與 一個介於0~360度的方向有關。例如,每一條測量數據也包含風吹來的方向(圖9-17)。
為了更好地分析這類數據,有必要將其做成可視化形式,但是對於風力數據,將其制作成使用笛卡兒坐標系的線性圖不再是最佳選擇。
要是把一個DataFrame中的數據點做成散點圖
plt.plot(df_ravenna['wind_deg'],df_ravenna['wind_speed'],'ro')
就會得到圖9-18這樣的圖表,很顯然該圖的表現力也有不足。
要表示呈360度分布的數據點,最好使用另一種可視化方法:極區圖。
首先,創建一個直方圖,也就是將360度分為八個面元,每個面元為45度,把所有的數據點分到這八個面元中。
hist, bins = np.histogram(df_ravenna['wind_deg'],8,[0,360])
print hist
print bins
histogram()函數返回結果中的數組hist為落在每個面元的數據點數量。
[ 0 5 11 1 0 1 0 0]
返回結果中的數組bins定義了360度范圍內各面元的邊界。
[ 0. 45. 90. 135. 180. 225. 270. 315. 360.]
要想正確定義極區圖,離不開這兩個數組。我們將創建一個函數來繪制極區圖,其中部分代碼在第7章已講過。我們把這個函數定義為showRoseWind(),它有三個參數:values數組,指的是想為其作圖的數據,也就是這里的hist數組;第二個參數city_name為字符串類型,指定圖表標題所用的城市名稱;最后一個參數max_value為整型,指定最大的藍色值。
定義這樣一個函數很有用,它既能避免多次重復編寫相同的代碼,還能增強代碼的模塊化程度,便於你把精力放到與函數內部操作相關的概念上。
def showRoseWind(values,city_name,max_value):
N = 8
# theta = [pi*1/4, pi*2/4, pi*3/4, ..., pi*2]
theta = np.arange(0.,2 * np.pi, 2 * np.pi / N)
radii = np.array(values)
# 繪制極區圖的坐標系
plt.axes([0.025, 0.025, 0.95, 0.95], polar=True)
# 列表中包含的是每一個扇區的 rgb 值,x越大,對應的color越接近藍色
colors = [(1-x/max_value, 1-x/max_value, 0.75) for x in radii]
# 畫出每個扇區
plt.bar(theta, radii, width=(2*np.pi/N), bottom=0.0, color=colors)
# 設置極區圖的標題
plt.title(city_name, x=0.2, fontsize=20)
你需要修改變量colors存儲的顏色表。這里,扇形的顏色越接近藍色,值越大。定義好函數之后,調用它即可:
showRoseWind(hist,'Ravenna',max(hist))
運行上述函數,將得到如圖9-19所示的極區圖。
由圖9-19可見,整個360度的范圍被分成八個區域(面元),每個區域弧長為45度,此外每個區域還有一列呈放射狀排列的刻度值。在每個區域中,用半徑長度可以改變的扇形表示一個數值,半徑越長,扇形所表示的數值就越大。為了增強圖表的可讀性,我們使用與扇形半徑相對應的顏色表。半徑越長,扇形跨度越大,顏色越接近於深藍色。
從剛得到的極區圖可以得知風向在極坐標系中的分布方式。該圖表示這一天大部分時間風都 吹向西南和正西方向。
定義好showRoseWind()函數之后,查看其他城市的風向情況也非常簡單。
hist, bin = np.histogram(df_ferrara['wind_deg'],8,[0,360])
print hist
showRoseWind(hist,'Ferrara', max(hist))
計算風速均值的分布情況
即使是跟風速相關的其他數據,也可以用極區圖來表示。
定義RoseWind_Speed函數,計算將360度范圍划分成的八個面元中每個面元的平均風速。
def RoseWind_Speed(df_city):
# degs = [45, 90, ..., 360]
degs = np.arange(45,361,45)
tmp = []
for deg in degs:
# 獲取 wind_deg 在指定范圍的風速平均值數據
tmp.append(df_city[(df_city['wind_deg']>(deg-46)) & (df_city['wind_deg']<deg)]
['wind_speed'].mean())
return np.array(tmp)
這里 df_city[(df_city['wind_deg']>(deg-46)) & (df_city['wind_deg']<deg)] 獲取的是風向大於 'deg-46' 度和風向小於 'deg' 的數據。
RoseWind_Speed() 函數返回一個包含八個平均風速值的NumPy數組。該數組將作為先前定義的showRoseWind()函數的第一個參數,這個函數是用來繪制極區圖的。
showRoseWind(RoseWind_Speed(df_ravenna),'Ravenna',max(hist))
圖9-21所示的風向頻率玫瑰圖表示風速在360度范圍內的分布情況。
六、實驗總結
本章主要目的是演示如何從原始數據獲取信息。其中有些信息無法給出重要結論,而有些信息能夠驗證假設,增加我們對系統狀態的認識,而找出這種信息也就意味着數據分析取得了成功。
如果學完本課程,對書籍其他內容感興趣歡迎點擊以下鏈接購買書籍:
