1. 程式人生 > 實用技巧 >【Python資料分析】新冠肺炎資料--分析二

【Python資料分析】新冠肺炎資料--分析二

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月中旬的新疆疫情較嚴重。