Python数据分析练习:北京、广州PM2.5空气质量分析(2)

<接上一篇>


2. 数据分析

2.1 空气质量等级的对比分析

广州2015年与2016年的空气质量等级对比,分别统计全年各个等级的次数占比(例如:Good占比 = Good次数/全年总测量次数)

In [18]:
gz2015_grade = df_gz2015.groupby(['Grade']).size()/len(df_gz2015)
In [19]:
gz2016_grade = df_gz2016.groupby(['Grade']).size()/len(df_gz2016)
In [20]:
bj2015_grade = df_bj2015.groupby(['Grade']).size()/len(df_bj2015)
In [21]:
bj2016_grade = df_bj2016.groupby(['Grade']).size()/len(df_bj2016)

为了更方便地进行对比,我们把两地两年的等级数据放到同一个DataFrame中:

In [22]:
# 定义一个空气质量等级索引
ix_grade = ['Good', 'Moderate', 'Unhealthy for Sensi', 'Unhealthy', 'Very Unhealthy', 'Hazardous','Beyond Index']
In [23]:
# 创建一个DataFrame对象,先把广州2015年的空气质量等级占比数据加进去
df_grade = pd.DataFrame(gz2015_grade, index = ix_grade, columns=['gz2015'])
In [24]:
# 接下来把其他三个等级数据也加进DataFrame中
df_grade['gz2016'] = gz2016_grade
df_grade['bj2015'] = bj2015_grade
df_grade['bj2016'] = bj2016_grade
In [25]:
# 查看我们获得的DataFrame,这里包含了两地两年的空气质量等级占比数据
df_grade
Out[25]:
  gz2015 gz2016 bj2015 bj2016
Good 0.746356 0.820680 0.476625 0.507838
Moderate 0.208163 0.162640 0.245989 0.259297
Unhealthy for Sensi 0.036851 0.012756 0.119820 0.107335
Unhealthy 0.007580 0.002698 0.059333 0.054926
Very Unhealthy 0.001050 0.001227 0.063719 0.048060
Hazardous NaN NaN 0.029436 0.020483
Beyond Index NaN NaN 0.005079 0.002060
In [26]:
# 使用饼图查看广州2016年空气质量等级占比
df_grade.ix[:,'gz2016'].plot.pie(title = 'Guangzhou 2016 AQI' ,autopct = '%.1f%%', fontsize = 12, figsize=(6,6))
Out[26]:
<matplotlib.axes._subplots.AxesSubplot at 0xb8e52b0>
 
     

为了更直观地进行对比,我们可以画出对比柱状图,分别包括:广州2015年和2016年对比、北京和广州2016年对比、北京2015年和2016年对比。

In [27]:
df_grade.ix[:,['gz2015','gz2016']].plot.bar(title='Guangzhou AQI 2015 vs 2016', figsize=(8,6),fontsize = 12 )
Out[27]:
<matplotlib.axes._subplots.AxesSubplot at 0xbd24e80>

In [28]:
df_grade.ix[:,['gz2016','bj2016']].plot.bar(title='2016 AQI Guangzhou vs Beijing', figsize=(8,6),fontsize = 12)
Out[28]:
<matplotlib.axes._subplots.AxesSubplot at 0xbe45048>

In [29]:
df_grade.ix[:,['bj2015','bj2016']].plot.bar(title='Beijing AQI 2015 vs 2016', figsize=(8,6),fontsize = 12)
Out[29]:
<matplotlib.axes._subplots.AxesSubplot at 0xc2f13c8>
 
     

从图表可以明显看出以下结论:

  1. 本地的不同年份对比,北京和广州的情况类似,本地2016年相比2015年,空气质量测量值良好和中等的占比提升了,不健康的占比下降了。可以说广州和北京的空气质量在好转。

  2. 广州和北京的同一年份对比,广州空气良好的比重比北京高,空气不健康的比重比北京低得多。在空气质量方面,广州人民比北京人民要幸福啊。

2.2 月度趋势和对比分析

接下来,我们从全年情况来看,分析空气质量随季节(月份)的变化趋势,以及两地的对比分析。

首先计算出两地两年的每月平均测量值:

In [30]:
# 计算两地两年的pm2.5测量值月度平均值
gz2015_month = df_gz2015.groupby(['Month'])['Value'].mean()
gz2016_month = df_gz2016.groupby(['Month'])['Value'].mean()
bj2015_month = df_bj2015.groupby(['Month'])['Value'].mean()
bj2016_month = df_bj2016.groupby(['Month'])['Value'].mean()

为了方便对比,把上述平均值放到同一个DataFrame中。

In [31]:
df_month = pd.DataFrame({'gz2015':gz2015_month}, index = np.arange(1,13))
In [32]:
df_month['gz2016'] = gz2016_month
df_month['bj2015'] = bj2015_month
df_month['bj2016'] = bj2016_month
In [33]:
df_month
Out[33]:
  gz2015 gz2016 bj2015 bj2016
1 70.210306 35.413352 107.914750 72.146703
2 67.240487 37.168622 96.737237 43.959538
3 41.238806 50.401372 89.274895 93.125168
4 39.898470 40.774242 78.855134 66.500000
5 29.328804 27.272340 60.128378 55.245614
6 17.942976 22.398148 54.397436 59.008427
7 23.121253 20.051034 55.083558 60.075239
8 31.863329 30.260606 44.647376 38.727395
9 37.368124 22.630048 47.089261 51.595833
10 42.043069 22.668975 72.812500 82.092266
11 38.402244 38.969144 124.822222 104.739191
12 38.302703 48.918033 161.956403 144.628032
In [34]:
df_month.ix[:, ['gz2015','gz2016']].plot(title='Guangzhou PM2.5 Monthly Avg. 2015 vs 2016', figsize=(8,4))
Out[34]:
<matplotlib.axes._subplots.AxesSubplot at 0xc39f0f0>

从以上折线图可以看出,广州地区春冬季空气质量较差,夏秋季空质量较好。2016年的大部分月份平均PM2.5值比2015年同期较低,只有3月和12月比2015年同期较高。

In [35]:
df_month.ix[:, ['bj2015','bj2016']].plot(title='Beijing PM2.5 Monthly Avg. 2015 vs 2016', figsize=(8,4))
Out[35]:
<matplotlib.axes._subplots.AxesSubplot at 0xcc4b160>

从以上折线图可以看出,北京地区全年的PM2.5值基本呈U字形,冬季空气质量特别差,春季较差,夏秋季空质量较好。2016年大部分月份平均PM2.5值与2015年同期基本持平,只1、2月比2015年同期有较大幅度下降。

In [36]:
df_month.ix[:, ['gz2016','bj2016']].plot(title='2016 PM2.5 Monthly Avg. Beijing vs Guangzhou', figsize=(8,4))
Out[36]:
<matplotlib.axes._subplots.AxesSubplot at 0xcef2e80>

从以上折线图可以看出,2016年广州全年各月份的PM2.5平均值都比北京低,其中12月的均值只有北京同期的三分之一。

2.3 每小时测量值对比分析

前面的对比分析,都不是直接把测量数据进行对比,而是进行了平均或分级处理,这样的处理虽然也能看出总体趋势,但是毕竟损失了一些信息。接下来,我们不再对数据进行变换处理,而是直接把每个按小时测量的数据进行一一对比,计算出大于、等于和小于的次数。

为了方便操作,我们把两地两年的四个DataFrame合并在一起,行索引为('Month', 'Day', 'Hour'),列索引为('gz2015','gz2016','bj2015','bj2016')。

以下是合并重新生成一个DataFrame的过程。

In [37]:
df_hour = pd.DataFrame({'Month': df_gz2015.ix[:,'Month'], 
                        'Day'  : df_gz2015.ix[:,'Day'],
                        'Hour' : df_gz2015.ix[:,'Hour'],
                        'gz2015':df_gz2015.ix[:,'Value']})
In [38]:
df_hour.describe()
Out[38]:
  Day Hour Month gz2015
count 8575.000000 8575.000000 8575.000000 8575.000000
mean 15.576676 11.507172 6.497726 39.499942
std 8.752709 6.931227 3.428460 29.009505
min 1.000000 0.000000 1.000000 1.000000
25% 8.000000 5.000000 4.000000 19.000000
50% 16.000000 12.000000 7.000000 32.000000
75% 23.000000 18.000000 9.000000 51.000000
max 31.000000 23.000000 12.000000 259.000000

下面先把广州2016年的数据合并进去

In [39]:
df_hour = df_hour.merge(df_gz2016.ix[:,['Month','Day','Hour','Value']], on=('Month','Day','Hour'))
In [40]:
df_hour.rename_axis({'Value':'gz2016'}, axis="columns", inplace=True)
In [41]:
df_hour.describe()
Out[41]:
  Day Hour Month gz2015 gz2016
count 7957.000000 7957.000000 7957.000000 7957.000000 7957.000000
mean 15.564032 11.541033 6.556994 39.967827 33.130325
std 8.808309 6.935092 3.463692 29.553651 24.323558
min 1.000000 0.000000 1.000000 1.000000 0.000000
25% 8.000000 6.000000 4.000000 19.000000 16.000000
50% 15.000000 12.000000 7.000000 33.000000 28.000000
75% 23.000000 18.000000 10.000000 51.000000 44.000000
max 31.000000 23.000000 12.000000 259.000000 266.000000

合并主要使用了merge方法,可以确保合并时在月、日、时三个索引上一一对应,对应不上(例如某个时间有测量数据缺失),则只保留交集部分,其他的丢弃。从合并前后的DataFrame描述来看,记录数有减少,这是因为有些未交集的记录丢弃了。

下面用同样的方法,把北京2015和2016年的数据合并进去。

In [42]:
df_hour = df_hour.merge(df_bj2015.ix[:,['Month','Day','Hour','Value']], on=('Month','Day','Hour'))
df_hour.rename_axis({'Value':'bj2015'}, axis="columns", inplace=True)

df_hour = df_hour.merge(df_bj2016.ix[:,['Month','Day','Hour','Value']], on=('Month','Day','Hour'))
df_hour.rename_axis({'Value':'bj2016'}, axis="columns", inplace=True)
In [43]:
df_hour.head()
Out[43]:
  Day Hour Month gz2015 gz2016 bj2015 bj2016
0 1 0 1 38.0 55.0 22.0 231.0
1 1 1 1 40.0 58.0 9.0 239.0
2 1 2 1 40.0 59.0 9.0 205.0
3 1 3 1 34.0 58.0 13.0 167.0
4 1 4 1 42.0 51.0 10.0 132.0
In [44]:
df_hour.describe()
Out[44]:
  Day Hour Month gz2015 gz2016 bj2015 bj2016
count 7833.000000 7833.000000 7833.000000 7833.000000 7833.000000 7833.000000 7833.000000
mean 15.493681 11.534661 6.567471 39.947530 33.131750 81.893527 70.324269
std 8.805105 6.954496 3.465844 29.546365 24.352084 87.343633 75.638957
min 1.000000 0.000000 1.000000 1.000000 0.000000 0.000000 0.000000
25% 8.000000 6.000000 4.000000 19.000000 16.000000 22.000000 17.000000
50% 15.000000 12.000000 7.000000 33.000000 28.000000 55.000000 47.000000
75% 23.000000 18.000000 10.000000 51.000000 44.000000 108.000000 92.000000
max 31.000000 23.000000 12.000000 259.000000 266.000000 722.000000 782.000000
In [45]:
df_hour.head()
Out[45]:
  Day Hour Month gz2015 gz2016 bj2015 bj2016
0 1 0 1 38.0 55.0 22.0 231.0
1 1 1 1 40.0 58.0 9.0 239.0
2 1 2 1 40.0 59.0 9.0 205.0
3 1 3 1 34.0 58.0 13.0 167.0
4 1 4 1 42.0 51.0 10.0 132.0

下面进行逐个对比。

In [46]:
len(df_hour[df_hour['gz2015']>df_hour['gz2016']]), 1.0*len(df_hour[df_hour['gz2015']>df_hour['gz2016']])/len(df_hour)
Out[46]:
(4366, 0.5573854206561981)
In [47]:
len(df_hour[df_hour['gz2015']<df_hour['gz2016']]),1.0*len(df_hour[df_hour['gz2015']<df_hour['gz2016']])/len(df_hour)
Out[47]:
(3342, 0.4266564534661049)

从上述结果中看出,

广州地区2016年有4366次PM2.5测量值比2015年同期小,占比55.7%,

有3342次比2015年同期大,占比42.7%。

可以从总体上来说,2016年的空气质量比2015年好。

也可以画出曲线图进行更直观的对比。

In [48]:
df_hour.ix[:, ['gz2015','gz2016']].plot(title='Guangzhou PM2.5 Hourly 2015 vs 2016', figsize=(12,4))
Out[48]:
<matplotlib.axes._subplots.AxesSubplot at 0xd1d6a58>

In [49]:
len(df_hour[df_hour['bj2016']>df_hour['gz2016']]), 1.0*len(df_hour[df_hour['bj2016']>df_hour['gz2016']])/len(df_hour)
Out[49]:
(5153, 0.657857781182178)
In [50]:
len(df_hour[df_hour['bj2016']<df_hour['gz2016']]), 1.0*len(df_hour[df_hour['bj2016']<df_hour['gz2016']])/len(df_hour)
Out[50]:
(2581, 0.32950338312268607)

从上述结果中看出,

广州地区2016年有5153次PM2.5测量值比北京同期小,占比65.8%,

有2581次比北京同期大,占比33%。

可以从总体上来说,广州的空气质量比北京好。

也可以画出曲线图进行更直观的对比。

In [51]:
df_hour.ix[:, ['bj2016','gz2016']].plot(title='2016 PM2.5 Hourly Beijing vs Guangzhou', figsize=(12,4))
Out[51]:
<matplotlib.axes._subplots.AxesSubplot at 0xd6834a8>

3. 分析结论

根据美国大使馆/领事馆的PM2.5测量数据,可以得出以下结论:

  1. 广州的空气质量总体还是不错的,质量等级健康占82.1%,中等占16.3%,也就是说绝大多数时段的空气质量都比较好。
  2. 2016年与2015年相比,广州市的空气质量是有所改善,改善幅度不是很大
  3. 2016年,广州的空气质量比北京要好很多

当然,以上分析结论都是基于美国大使馆/领事馆的测量数据,受到测量仪器的准确性、测量点的地理位置等因素的影响。

4. 总结

本文通过一个PM2.5数据分析的案例,对Python数据分析的技术和方法进行了一次演练。其中主要用到了Python pandas包,想要更详细地了解pandas包,可以访问官方网站:http://pandas.pydata.org/ ,其中API文档:http://pandas.pydata.org/pandas-docs/stable/api.html


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值