【Python資料分析】新冠肺炎資料--分析二
阿新 • • 發佈:2020-10-25
2、疫情資料分析(二)
Δ本篇主要知識點:(1)pandas一階差分、重取樣、資料重塑、分組、資料合併、isin函式、空DataFrame迴圈新增行;(2)seaborn繪圖。
1 import pandas as pd 2 import matplotlib.pyplot as plt 3 import seaborn as sns 4 from datetime import datetime
1 #將matplotlib的預設字型改為仿宋,以在圖形中顯示中文。 2 plt.rcParams['font.sans-serif']=['fangsong'] 3 #在多語種情形下正確顯示負號4 plt.rcParams['axes.unicode_minus']=False 5 #解決matplotlib丟擲的max_open_warning 6 plt.rcParams.update({'figure.max_open_warning': 0})
1 covid_cases_cumsum=pd.read_csv(r'C:\Users\92342\Desktop\python\Python資料分析學習之路\1、疫情資料\covid_cases_cumsum.csv',\ 2 parse_dates=[0],index_col=[0])3 print(covid_cases_cumsum.head())
全國 北京 天津 河北 山西 內蒙古 遼寧 吉林 黑龍江 上海 ... 重慶 四川 貴州 雲南 \ 2020-01-16 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN 2020-01-17 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN 2020-01-18 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN 2020-01-19 NaN NaN NaN NaN NaN NaN NaN NaN NaN 0.0 ... NaN NaN NaN NaN 2020-01-20 291.0 NaN NaN NaN NaN NaN NaN NaN NaN 2.0 ... NaN NaN NaN NaN 西藏 陝西 甘肅 青海 寧夏 新疆 2020-01-16 NaN NaN NaN NaN NaN NaN 2020-01-17 NaN NaN NaN NaN NaN NaN 2020-01-18 NaN NaN NaN NaN NaN NaN 2020-01-19 NaN NaN NaN NaN NaN 0.0 2020-01-20 NaN NaN NaN NaN NaN 0.0 [5 rows x 32 columns]
問題3:每日確診病例資料走勢如何?
使用一階差分函式pandas.diff(),由累計值轉變為單日值。
1 covid_cases_everyday=covid_cases_cumsum.diff(periods=1,axis=0)
1 #使用seaborn.lineplot()繪製全國確診病例每日資料的變化 2 fig,ax=plt.subplots() 3 ax=sns.lineplot(data=covid_cases_everyday['全國']) 4 ax.set_title('新冠肺炎每日確診病例:全國') 5 ax.set_ylabel('確診病例') 6 fig.tight_layout() 7 plt.show()
1 #檢視新冠肺炎確診病例日均值 2 covid_cases=covid_cases_everyday['全國'].sum() 3 covid_cases
85381.0
從每日資料變化圖看,新冠肺炎每日確診病例迅速上升再迅速下降,可見疫情發展之猛烈、防控力度之大。
問題4:各月確診病例最多的省份是哪裡?
1 #按月重取樣,取樣方式為彙總 2 covid_cases_by_month=covid_cases_everyday.resample('M').sum()
注意到資料集是“寬資料”(並非每列都是變數,與疫情病例相關的值按地區分佈在多列中),可將資料重塑為“長資料”,即進行逆透視/融合/聚合處理。
1 #先將covid_cases_by_month的DatetimeIndex設為一列,名為month 2 covid_cases_by_month['month']=covid_cases_by_month.index 3 #對covid_cases_by_month使用pd.melt()方法,month列保持原樣,融合後的新列名為area,融合後新列的值名為count 4 covid_cases_by_month_long=pd.melt(covid_cases_by_month,id_vars='month',var_name='area',value_name='count')
1 #由於全國資料包含了各省資料,因此先分拆為全國資料、各省資料集2個數據集。 2 covid_month_country=covid_cases_by_month_long[covid_cases_by_month_long['area']=='全國'] 3 covid_month_province=covid_cases_by_month_long[~(covid_cases_by_month_long['area']=='全國')]
1 #利用groupby方法獲取各省月度的最大值,再使用pd.isin()方法篩選出月度資料最大的省份 2 max_of_month=covid_month_province.groupby('month')['count'].max() 3 covid_month_max_province=covid_month_province[covid_month_province['count'].isin(list(max_of_month))] 4 covid_month_max_province.sort_values(by='month')
month area count 170 2020-01-31 湖北 7108.0 171 2020-02-29 湖北 59754.0 172 2020-03-31 湖北 895.0 83 2020-04-30 黑龍江 460.0 74 2020-05-31 吉林 44.0 15 2020-06-30 北京 329.0 316 2020-07-31 新疆 563.0 317 2020-08-31 新疆 263.0 98 2020-09-30 上海 102.0 278 2020-09-30 陝西 44.0 99 2020-10-31 上海 79.0
month area count 170 2020-01-31 湖北 7108.0 171 2020-02-29 湖北 59754.0 172 2020-03-31 湖北 895.0 83 2020-04-30 黑龍江 460.0 74 2020-05-31 吉林 44.0 15 2020-06-30 北京 329.0 316 2020-07-31 新疆 563.0 317 2020-08-31 新疆 263.0 98 2020-09-30 上海 102.0 278 2020-09-30 陝西 44.0 99 2020-10-31 上海 79.0
1 #使用pd.merge()方法合併全國、各省2個數據集 2 covid_month_country_whole=covid_month_country.merge(covid_month_max_province,left_on='month',right_on='month') 3 covid_month_country_whole
month area_x count_x area_y count_y 0 2020-01-31 全國 11499.0 湖北 7108.0 1 2020-02-29 全國 68034.0 湖北 59754.0 2 2020-03-31 全國 1730.0 湖北 895.0 3 2020-04-30 全國 1320.0 黑龍江 460.0 4 2020-05-31 全國 143.0 吉林 44.0 5 2020-06-30 全國 517.0 北京 329.0 6 2020-07-31 全國 803.0 新疆 563.0 7 2020-08-31 全國 721.0 新疆 263.0 8 2020-09-30 全國 356.0 上海 102.0 9 2020-09-30 全國 356.0 陝西 44.0 10 2020-10-31 全國 258.0 上海 79.0
1 #修改area_x、count_x、area_y、area_y等列名,並新增一列計算每月病例最多的省份佔全國病例數的比重 2 covid_month_country_whole=covid_month_country_whole.rename(columns={'area_x':'country','count_x':'count_country','area_y':'max_province','count_y':'count_max_province'}) 3 covid_month_country_whole['prop_maxprovince_of_country']=covid_month_country_whole['count_max_province']/covid_month_country_whole['count_country'] 4 covid_month_country_whole
month country count_country max_province count_max_province prop_maxprovince_of_country 0 2020-01-31 全國 11499.0 湖北 7108.0 0.618141 1 2020-02-29 全國 68034.0 湖北 59754.0 0.878296 2 2020-03-31 全國 1730.0 湖北 895.0 0.517341 3 2020-04-30 全國 1320.0 黑龍江 460.0 0.348485 4 2020-05-31 全國 143.0 吉林 44.0 0.307692 5 2020-06-30 全國 517.0 北京 329.0 0.636364 6 2020-07-31 全國 803.0 新疆 563.0 0.701121 7 2020-08-31 全國 721.0 新疆 263.0 0.364771 8 2020-09-30 全國 356.0 上海 102.0 0.286517 9 2020-09-30 全國 356.0 陝西 44.0 0.123596 10 2020-10-31 全國 258.0 上海 79.0 0.306202
可以看出,2020年1-3月,月病例最多的省份為湖北,湖北病例佔全國的比重分別為0.45、0.88、0.51。¶
2020年4-5月,月病例最多的省份分別為黑龍江、吉林,東北成為疫情最嚴重地區。 2020年6月,月病例最多省份為北京,且北京病例佔全國的比重的比例高達0.64. 2020年7-8月,全國疫情最嚴重地區為新疆。2020年9-10月,全國疫情最嚴重地區為上海。
第9行的陝西省資料不應出現,猜測原因為陝西2020年9月病例數為44,正好與2020年5月吉林的值一樣,在pd.isin()方法中也被判定為TRUE,有待進一步改進。
問題5:各周確診病例最多的省份分別是哪裡?
1 #按周檢視新冠肺炎確診病例彙總值 2 covid_cases_by_week=covid_cases_everyday.resample('W').sum() 3 print(covid_cases_by_week['湖北'].head())
2020-01-19 153.0
2020-01-26 1225.0
2020-02-02 9754.0
2020-02-09 18454.0
2020-02-16 28513.0
Freq: W-SUN, Name: 湖北, dtype: float64
1 covid_cases_by_week['week']=covid_cases_by_week.index 2 covid_cases_by_week=covid_cases_by_week.melt(id_vars='week',var_name='area',value_name='count') 3 covid_cases_by_week
week area count 0 2020-01-19 全國 0.0 1 2020-01-26 全國 2453.0 2 2020-02-02 全國 14459.0 3 2020-02-09 全國 22955.0 4 2020-02-16 全國 30392.0 ... ... ... ... 1275 2020-09-20 新疆 0.0 1276 2020-09-27 新疆 0.0 1277 2020-10-04 新疆 0.0 1278 2020-10-11 新疆 0.0 1279 2020-10-18 新疆 0.0 1280 rows × 3 columns
1 #拆分為全國資料集、各省資料集。 2 covid_cases_by_week_country=covid_cases_by_week[covid_cases_by_week['area']=='全國'] 3 covid_cases_by_week_province=covid_cases_by_week[~(covid_cases_by_week['area']=='全國')] 4 covid_cases_by_week_province.to_csv('./1、疫情資料/covid_cases_by_week_province.csv')
1 #獲取各周病例最多的省份 2 #注意pd.isin()的引數應為列表 3 covid_cases_by_week_maxvalue=covid_cases_by_week_province.groupby('week')['count'].max() 4 covid_cases_by_week_maxprovince=covid_cases_by_week_province[covid_cases_by_week_province['count'].isin(list(covid_cases_by_week_maxvalue))] 5 covid_cases_by_week_maxprovince.sort_values(by='week')
week area count 680 2020-01-19 湖北 153.0 201 2020-01-26 內蒙古 10.0 521 2020-01-26 福建 55.0 321 2020-01-26 黑龍江 19.0 121 2020-01-26 河北 17.0 ... ... ... ... 1118 2020-10-11 陝西 15.0 798 2020-10-11 廣東 20.0 799 2020-10-18 廣東 20.0 399 2020-10-18 上海 32.0 119 2020-10-18 天津 7.0 121 rows × 3 columns
周度情形下,pd.isin(list)中的list重複值很多,結果存在明顯錯誤(如2020年1月最嚴重省份應為湖北)
現在採用另一種方法獲取每週病例最多的省份。
1 #首先獲取周列表 2 week_list=list(covid_cases_by_week_province['week'].unique()) 3 #week_list是一個datetime列表 4 print(week_list[0]) 5 print(str(week_list[0]))
2020-01-19T00:00:00.000000000 2020-01-19T00:00:00.000000000
1 #將week_list轉換為一個字串列表。 2 week_list=[str(i)[:10] for i in week_list] 3 print(week_list)
['2020-01-19', '2020-01-26', '2020-02-02', '2020-02-09', '2020-02-16', '2020-02-23', '2020-03-01', '2020-03-08', '2020-03-15', '2020-03-22', '2020-03-29', '2020-04-05', '2020-04-12', '2020-04-19', '2020-04-26', '2020-05-03', '2020-05-10', '2020-05-17', '2020-05-24', '2020-05-31', '2020-06-07', '2020-06-14', '2020-06-21', '2020-06-28', '2020-07-05', '2020-07-12', '2020-07-19', '2020-07-26', '2020-08-02', '2020-08-09', '2020-08-16', '2020-08-23', '2020-08-30', '2020-09-06', '2020-09-13', '2020-09-20', '2020-09-27', '2020-10-04', '2020-10-11', '2020-10-18']
1 #先建立一個空的DataFrame,再遍歷每一週,將該周病例最多的省份新增為新建的DataFrame的一行 2 covid_cases_by_week_maxprovince=pd.DataFrame(columns=['week','area','count']) 3 for i in week_list: 4 covid_cases_iweek=covid_cases_by_week_province[covid_cases_by_week_province['week']==i] 5 covid_cases_iweek_max=covid_cases_iweek[covid_cases_iweek['count']==covid_cases_iweek['count'].max()] 6 covid_cases_by_week_maxprovince= covid_cases_by_week_maxprovince.append(covid_cases_iweek_max,ignore_index=True) 7 8 print(covid_cases_by_week_maxprovince)
week area count 0 2020-01-19 湖北 153.0 1 2020-01-26 湖北 1225.0 2 2020-02-02 湖北 9754.0 3 2020-02-09 湖北 18454.0 4 2020-02-16 湖北 28513.0 5 2020-02-23 湖北 6143.0 6 2020-03-01 湖北 2816.0 7 2020-03-08 湖北 640.0 8 2020-03-15 湖北 55.0 9 2020-03-22 北京 76.0 10 2020-03-29 上海 94.0 11 2020-04-05 廣東 48.0 12 2020-04-12 黑龍江 216.0 13 2020-04-19 湖北 325.0 14 2020-04-26 黑龍江 31.0 15 2020-05-03 陝西 20.0 16 2020-05-10 吉林 15.0 17 2020-05-17 吉林 19.0 18 2020-05-24 內蒙古 14.0 19 2020-05-31 四川 11.0 20 2020-06-07 廣東 7.0 21 2020-06-14 北京 79.0 22 2020-06-21 北京 157.0 23 2020-06-28 北京 82.0 24 2020-07-05 北京 17.0 25 2020-07-12 內蒙古 10.0 26 2020-07-19 新疆 47.0 27 2020-07-26 新疆 131.0 28 2020-08-02 新疆 442.0 29 2020-08-09 新疆 157.0 30 2020-08-16 新疆 49.0 31 2020-08-23 上海 52.0 32 2020-08-30 上海 23.0 33 2020-09-06 廣東 28.0 34 2020-09-13 上海 25.0 35 2020-09-20 上海 27.0 36 2020-09-27 廣東 19.0 37 2020-10-04 上海 30.0 38 2020-10-11 上海 31.0 39 2020-10-18 上海 32.0
1 #合併全國、各省兩個資料集 2 covid_cases_week_whole=covid_cases_by_week_country.merge(covid_cases_by_week_maxprovince,left_on='week',right_on='week') 3 #重新命名列 4 covid_cases_week_whole=covid_cases_week_whole.rename(columns={'area_x':'country','count_x':'count_country','area_y':'maxprovince','count_y':'count_maxprovince'}) 5 #新增一列 6 covid_cases_week_whole['prop_maxprovince_of_country']=covid_cases_week_whole['count_maxprovince']/covid_cases_week_whole['count_country'] 7 covid_cases_week_whole
week country count_country maxprovince count_maxprovince prop_maxprovince_of_country 0 2020-01-19 全國 0.0 湖北 153.0 inf 1 2020-01-26 全國 2453.0 湖北 1225.0 0.499389 2 2020-02-02 全國 14459.0 湖北 9754.0 0.674597 3 2020-02-09 全國 22955.0 湖北 18454.0 0.803921 4 2020-02-16 全國 30392.0 湖北 28513.0 0.938175 5 2020-02-23 全國 6600.0 湖北 6143.0 0.930758 6 2020-03-01 全國 2876.0 湖北 2816.0 0.979138 7 2020-03-08 全國 709.0 湖北 640.0 0.902680 8 2020-03-15 全國 125.0 湖北 55.0 0.440000 9 2020-03-22 全國 233.0 北京 76.0 0.326180 10 2020-03-29 全國 377.0 上海 94.0 0.249337 11 2020-04-05 全國 238.0 廣東 48.0 0.201681 12 2020-04-12 全國 452.0 黑龍江 216.0 0.477876 13 2020-04-19 全國 587.0 湖北 325.0 0.553663 14 2020-04-26 全國 83.0 黑龍江 31.0 0.373494 15 2020-05-03 全國 50.0 陝西 20.0 0.400000 16 2020-05-10 全國 38.0 吉林 15.0 0.394737 17 2020-05-17 全國 36.0 吉林 19.0 0.527778 18 2020-05-24 全國 31.0 內蒙古 14.0 0.451613 19 2020-05-31 全國 32.0 四川 11.0 0.343750 20 2020-06-07 全國 23.0 廣東 7.0 0.304348 21 2020-06-14 全國 141.0 北京 79.0 0.560284 22 2020-06-21 全國 215.0 北京 157.0 0.730233 23 2020-06-28 全國 116.0 北京 82.0 0.706897 24 2020-07-05 全國 45.0 北京 17.0 0.377778 25 2020-07-12 全國 45.0 內蒙古 10.0 0.222222 26 2020-07-19 全國 80.0 新疆 47.0 0.587500 27 2020-07-26 全國 209.0 新疆 131.0 0.626794 28 2020-08-02 全國 537.0 新疆 442.0 0.823091 29 2020-08-09 全國 240.0 新疆 157.0 0.654167 30 2020-08-16 全國 181.0 新疆 49.0 0.270718 31 2020-08-23 全國 118.0 上海 52.0 0.440678 32 2020-08-30 全國 81.0 上海 23.0 0.283951 33 2020-09-06 全國 86.0 廣東 28.0 0.325581 34 2020-09-13 全國 60.0 上海 25.0 0.416667 35 2020-09-20 全國 97.0 上海 27.0 0.278351 36 2020-09-27 全國 81.0 廣東 19.0 0.234568 37 2020-10-04 全國 98.0 上海 30.0 0.306122 38 2020-10-11 全國 108.0 上海 31.0 0.287037 39 2020-10-18 全國 94.0 上海 32.0 0.340426
1 #將week列轉為datetime型別,以正確顯示日期座標軸 2 covid_cases_week_whole['week_datetime']=covid_cases_week_whole['week'].dt.strftime('%Y-%m-%d') 3 #設定較大的圖形尺寸,否則座標軸會重疊 4 fig=plt.figure(figsize=(20,10)) 5 ax=fig.add_subplot(1,1,1) 6 #著色引數hue設定為按省份著色 7 ax=sns.scatterplot(x='week_datetime',y='prop_maxprovince_of_country',hue='maxprovince',s=200,data=covid_cases_week_whole) 8 #使日期座標軸自適應顯示(否則全部橫排也會重疊在一起) 9 fig.autofmt_xdate() 10 #顯示網格線,並設定為虛線 11 plt.grid(linestyle='--') 12 #設定圖例為最大 13 plt.legend(fontsize='xx-large') 14 ax.set_title('周度確診病例最多的省份佔全國病例的比重',size=20) 15 ax.set_xlabel('') 16 ax.set_ylabel('') 17 plt.savefig(r'./1、疫情資料/周度確診病例最多的省份.png') 18 plt.show()
通過上圖,我們可以得出結論:
1、從疫情爆發至2020年3月15日,每週確診病例最多的省份均為湖北,湖北病例佔全國的比重先是急劇攀升,然後維持在很高的水平,直到2020年3月中旬比重才迅速下降。
2、2020年3月15日起,確診病例最多的省份更替頻繁,且佔比都不是很高,例外情況是北京、新疆,6月中旬至7月初的北京、7月中旬到8月中旬的新疆疫情較嚴重。