全國空氣質量分析

本文基於2017年全國367個城市每日的空氣質量數據(包括AQI, 綜合指數,PM2.5,PM10,CO,NO2,SO2,O3_1,O3_8,風力,溼度,降水,氣溫等12個日均值指標),通過Stata軟件編寫爬蟲程序獲取數據,並採用python軟件基於獲取到的數據探究全國空氣質量與各污染物之間的關係。

一、項目摘要

本項目使用python中的pandas/numpy庫對空氣質量數據進行導入及清洗,並使用matplotlib/seaborn/pyecharts工具包可視化分析2017年全國主要省市的空氣質量情況,對空氣質量最差及最好的省市進行排名,利用相關性分析省市的主要污染物,從不同層面給出污染物指標控制方案。

二、問題提出

全國範圍:
全國哪些城市污染較嚴重,那些省份污染較嚴重?(AQI作爲判斷依據)
污染較嚴重省份的主要污染物是什麼?
污染較嚴重城市的主要污染物是什麼?
全國哪個季節的污染最嚴重?

三、數據獲取

空氣質量網站:http://pm.kksk.org/
在這裏插入圖片描述
空氣質量數據所在地址:(以北京爲例)http://pm.kksk.org/fxzx/ccl.php?city=%B1%B1%BE%A9&ts=20190101&te=20171231&t_aqi=on&t_zhzs=on&t_pm25=on&t_pm10=on&t_co=on&t_no2=on&t_so_2=on&t_o3_1=on&t_o3_8=on&c_fengli=on&c_shidu=on&c_jiangshui=on&c_qiwen=on&data=day
注:實際是367個城市

  • 獲取城市列表-城市所對應的GB2312編碼-省份
    http://pm.kksk.org/citylist.php
  • 編寫程序獲取數據,並進行缺失值的基本處理
clear
cd C:/smile的文件夾/空氣
#城市.dta包括城市,ci(城市對應的GB2312編碼),指標(空氣質量指標)
use 城市.dta,clear  
levelsof ci,local(city)
levelsof 指標,local(quality)
foreach cit in `city' {
	foreach q in `quality' {
	copy "http://pm.kksk.org/fxzx/ccl.php?city=`cit'&ts=20170101&te=20171231&t_`q'=on&data=day" "C:\smile的文件夾\空氣\城市指標/`cit'`q'.txt"
	infix strL v 1-100000 using C:\smile的文件夾\空氣\城市指標/`cit'`q'.txt, clear
	replace v = ustrfrom(v, "gb18030", 1)
	keep if index(v, "{type:")
	split v,p(",")
	drop v-v8
	replace v9=substr(v9,8,.)
	sxpose,clear
	replace _var1="-1000" if _var1=="null"
	destring _var1,replace
	replace _var1=substr(_var1,1,index(_var1,"]")-1) in -1
	destring _var1,replace
	rename _var1 `q'
	gen id=_n
	gen ci1="`c'"
	merge m:m ci1 using 城市2.dta
	keep if _merge==3
	drop _merge
	drop ci1
	local c=城市
	order 城市 id `q'
	save C:\smile的文件夾\空氣\處理數據/`c'`q'.dta
	}
	}

因數據獲取較爲簡單,故此處不做重點介紹。
獲取到的數據爲dta格式,接下來對數據進行分析處理。

四、數據分析

在這裏插入圖片描述
1.數據描述

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
#%matplotlib inline 可以在Ipython編譯器裏直接使用,
#功能是可以內嵌繪圖,並且可以省略掉plt.show()這一步。
df=pd.read_stata(r'C:\smile的文件夾\空氣\全國空氣質量數據.dta')
df.head()

在這裏插入圖片描述

#更改變量名稱
df.rename(columns={'城市':'cityname'},inplace=True)
pro=pd.read_stata(r'C:\smile的文件夾\空氣\省份.dta')
pro.rename(columns={'省份':'province','城市':'cityname'},inplace=True)
#數據合併
df=pd.merge(df,pro,on='cityname',how='left')
df.shape  #(133948, 15),133948行15列
df.cityname.value_counts().count() 
#367
df.describe()
df.info()

在這裏插入圖片描述
在這裏插入圖片描述
可見,

  • so_2,co,no2,o3_1,o3_8,pm10,pm25,zhzs,fengli,qiwen,shidu等變量包含缺失值,再加上獲取數據時將數據中的一些變量的缺失值用‘-1000’代替。故下面處理缺失值:so_2,co,no2,o3_8,pm10,pm25用所在城市均值填充,o3_1,zhzs,fengli,qiwen,shidu與本文研究無關,刪除此列;
  • 時間數據格式需要進行轉換,創建季節列;
  • 創建空氣質量等級列;
  • 列出每個城市所屬的省份;
  • 創建省份空氣質量排名列(以AQI爲基礎);
  • 創建城市空氣質量排名列(以AQI爲基礎)。
    2.數據清洗
#刪除無關變量
for i in ['zhzs','fengli','qiwen','shidu']:
    df.drop([i],axis=1,inplace=True)
#填補缺失值,首先將缺失值都換爲0,
#再使用for循環計算每個城市污染物的平均值後替換NaN值
for i in df.columns.values:
    df.loc[df[i]==-1000]=0
df[['so_2', 'aqi', 'co', 'no2', 'o3_1', 'o3_8','pm10', 'pm25']] = df[['so_2', 'aqi', 'co', 'no2', 'o3_1', 'o3_8','pm10', 'pm25']].replace(0, np.NaN)
df.isnull().sum() #將0值替換後缺失值的數量

在這裏插入圖片描述

#使用for循環計算每個城市污染物的平均值後替換NaN值
cities = df.cityname.value_counts().index
for city in cities:
    for pollutant in ['aqi', 'pm2_5', 'pm10', 'so2', 'no2', 'co', 'o3']:
        df.loc[(df['cityname'] == city) & (df[pollutant].isnull()), 
               pollutant] = df[df['cityname'] == city][pollutant].mean()
df.isnull().sum() # 再次檢查缺失值

轉換時間數據格式,創建季節列:

df['time'] = pd.to_datetime(df['id'])
df.info() #查看time列的數據類型
# 根據月份創建季節列
seasons = {12: 'Winter',
           1: 'Winter',
           2: 'Winter',
           3: 'Spring',
           4: 'Spring',
           5: 'Spring',
           6: 'Summer',
           7: 'Summer',
           8: 'Summer',
           9: 'Autumn',
           10: 'Autumn',
           11: 'Autumn'
} 
df['season'] = df['time'].apply(lambda x : seasons [x.month])
df.head()

創建空氣質量等級列

bin_edges = [0, 50, 100, 150, 200, 300, 1210] # 根據AQI的劃分等級設置標籤
bin_names = ['優級', '良好', '輕度污染', '中度污染', '重度污染', '重污染']
df['空氣質量'] = pd.cut(df['aqi'], bin_edges, labels=bin_names)
df.head()

創建省份空氣質量排名列(以AQI平均值爲基礎):

a = df.groupby('省份').mean().aqi.sort_values().index
b = []
for _ in range(1, a.shape[0]+1):
    b.append(_)
pro_rank_dic = dict(zip(a, b))
pro_rank_dic
# 匹配省名,增加排名列
df['所屬省份空氣質量排名'] = df['省份'].map(pro_rank_dic)
df.head()

創建城市空氣質量排名列(以AQI爲基礎):

c = df.groupby('cityname').mean().aqi.sort_values().index
d = []
for _ in range(1, c.shape[0]+1):
    d.append(_)
city_rank_dic = dict(zip(c, d))
city_rank_dic
# 匹配城市名,增加排名列
df['城市空氣質量全國排名'] = df['cityname'].map(city_rank_dic)
df.head()

3.構建模型

df.describe()
plt.figure(figsize=(25,5))
sns.heatmap(df.corr(), vmax=1, square=False, annot=True, linewidth=1)
plt.yticks(rotation=0);

在這裏插入圖片描述
與全國空氣質量有較大關係的污染物指標是pm10、so2、no2
全國範圍:
問題:全國哪些城市污染較嚴重,那些省份污染較嚴重?(AQI作爲判斷依據)

# 使用pyecharts模塊導入地圖,在地圖上顯示城市空氣質量
from pyecharts import Geo
keys = df.groupby('cityname').aqi.mean().index
values = df.groupby('cityname').aqi.mean().values
geo = Geo("全國主要城市空氣質量圖", "data from AQI", title_color="#fff",
          title_pos="left", width=800, height=600,background_color='#404a59')
# type有scatter, effectScatter, heatmap三種模式可選,可根據自己的需求選擇對應的圖表模式
geo.add("全國城市空氣質量圖", keys, values, visual_range=[38.072282, 193.755892], 
        type='effectScatter',visual_text_color="#fff", symbol_size=15,is_visualmap=True, is_roam=True) 
geo.render(path="全國主要城市空氣質量圖.html")

在這裏插入圖片描述
從地圖上可以看出,中國的北部內陸地區以及西北部地區空氣質量較差,沿海地區及高原地區空氣質量較好。

pd.DataFrame(df.groupby('cityname').aqi.mean().sort_values().tail(10)).plot.barh(figsize=(20,10))
plt.xlim(125,200)
plt.style.use('dark_background')
plt.title('全國空氣質量最差城市')
plt.xlabel('AQI')
plt.ylabel('城市名')
plt.legend('AQI')
plt.grid(linestyle=':', color='w')
plt.show();

在這裏插入圖片描述
全國空氣質量最差的10個城市/地區(排名分先後,差-好):
和田地區、喀什地區、保定、邢臺、阿克蘇地區、石家莊、克牧勒蘇州、衡水、邯鄲、安陽

pd.DataFrame(df.groupby('cityname').aqi.mean().sort_values(ascending=False).tail(10)).plot.barh(figsize=(20,10))
plt.style.use('dark_background')
plt.title('全國空氣質量十佳城市')
plt.xlabel('AQI')
plt.ylabel('城市名')
plt.xlim(37,47)
plt.legend('AQI')
plt.grid(linestyle=':', color='w')
plt.show();

在這裏插入圖片描述
全國空氣質量最好的10個城市/地區(排名分先後,好-差):
三亞、迪慶州、海口、麗江、黔西南州、怒江州、阿壩州、楚雄州、大理州、普洱

pd.DataFrame(df.groupby('省份').aqi.mean().sort_values().tail(10)).plot.barh(figsize=(20,10))
plt.style.use('dark_background')
plt.title('全國空氣質量最差省份')
plt.xlabel('AQI')
plt.ylabel('省份')
plt.xlim(85, 120)
plt.legend('AQI')
plt.grid(linestyle=':', color='w')
plt.show();

在這裏插入圖片描述
全國空氣質量最差的10個省份(排名分先後,差-好):
河北省、北京、河南省、天津、新疆、山東、山西、陝西、江蘇、湖北

pd.DataFrame(df.groupby('省份').aqi.mean().sort_values(ascending=False).tail(10)).plot.barh(figsize=(20,10))
plt.style.use('dark_background')
plt.title('全國空氣質量十佳省份')
plt.xlabel('AQI')
plt.ylabel('省份')
plt.xlim(40, 75)
plt.legend('AQI')
plt.grid(linestyle=':', color='w')
plt.show();

在這裏插入圖片描述
全國空氣質量最好的10個省份(排名分先後,好-差):
海南、雲南、福建、貴州、西藏、廣東、廣西、黑龍江、江西、青海
問題:污染較嚴重省份的主要污染物是什麼?

df_top10_polluted = []
df_top10_polluted = pd.DataFrame(df_top10_polluted)
for _ in range(0, 10):
    '''
    提取空氣質量最嚴重的省份信息
    '''
    temp = df[df['省份'] == df.groupby('省份').aqi.mean().sort_values().tail(10).index[_]]
    df_top10_polluted = pd.concat([df_top10_polluted, temp])
# 這裏只關注輕度污染以上時的污染物情況
df_overpolluted = df_top10_polluted[df_top10_polluted['aqi'] >= 100][['aqi', 'pm2_5', 'pm10', 'so2', 'no2', 'co', 'o3']] 
sns.regplot(x='pm2_5', y='aqi', data=df_overpolluted);

在這裏插入圖片描述

sns.regplot(x='pm10', y='aqi', data=df_overpolluted);

在這裏插入圖片描述

sns.regplot(x='so2', y='aqi', data=df_overpolluted);

在這裏插入圖片描述

sns.regplot(x='no2', y='aqi', data=df_overpolluted);

在這裏插入圖片描述

sns.regplot(x='co', y='aqi', data=df_overpolluted);

在這裏插入圖片描述

sns.regplot(x='o3', y='aqi', data=df_overpolluted);

在這裏插入圖片描述

plt.figure(figsize=(15,5))
sns.heatmap(df_overpolluted.corr(), vmax=1, square=False, annot=True, linewidth=1)
plt.yticks(rotation=0);

在這裏插入圖片描述
由線性關係圖和熱點圖可知,這十個空氣質量最差省份的主要污染物是pm10、so2、no2,這三種物質的高低對AQI值有較大影響,與AQI成正相關關係。此外,so2與no2兩者也表現出較強的正相關關係。
問題:污染較嚴重城市的主要污染物是什麼?

df_top10_polluted_city = []
df_top10_polluted_city = pd.DataFrame(df_top10_polluted_city)
for _ in range(0, 10):
    '''
    提取空氣質量最嚴重的城市信息
    '''
    temp = df[df['cityname'] == df.groupby('cityname').aqi.mean().sort_values().tail(10).index[_]]
    df_top10_polluted_city = pd.concat([df_top10_polluted_city, temp])
# 這裏只關注輕度污染以上時的污染物情況
df_overpolluted_city = df_top10_polluted_city[df_top10_polluted_city['aqi'] >= 100][['aqi', 'pm2_5', 'pm10',                                                                                'so2', 'no2', 'co', 'o3']] 
sns.regplot(x='pm2_5', y='aqi', data=df_overpolluted_city);

在這裏插入圖片描述

sns.regplot(x='pm10', y='aqi', data=df_overpolluted_city);

在這裏插入圖片描述

sns.regplot(x='so2', y='aqi', data=df_overpolluted_city);

在這裏插入圖片描述

sns.regplot(x='no2', y='aqi', data=df_overpolluted_city);

在這裏插入圖片描述

sns.regplot(x='co', y='aqi', data=df_overpolluted_city);

在這裏插入圖片描述

sns.regplot(x='o3', y='aqi', data=df_overpolluted_city);

在這裏插入圖片描述

plt.figure(figsize=(15,5))
sns.heatmap(df_overpolluted_city.corr(), vmax=1, square=False, annot=True, linewidth=1)
plt.yticks(rotation=0);

在這裏插入圖片描述
同樣,由線性關係圖和熱點圖可知,十個空氣質量最差城市的主要污染物是pm2.5、pm10、so2、no2,四種物質的高低對AQI值有較大影響,與AQI成正相關關係。其中值得注意的是pm2.5與城市空氣質量密切相關,但與省空氣質量相關性不是非常大。so2與no2之間、pm2.5與pm10、so2、no2之間表現出了較強的正相關關係,也就是說pm10、so2、no2三個指標中的某一指標的升高都會伴隨着pm2.5的升高。
問題:全國哪個季節的污染最嚴重?

pd.DataFrame(df.groupby('season').aqi.mean().sort_values()).plot.barh(figsize=(15,10))
plt.title('全國不同季節空氣質量情況')
plt.xlabel('AQI')
plt.ylabel('季節')
plt.xlim(60)
plt.legend('AQI')
plt.grid(linestyle=':', color='w')
plt.show();

在這裏插入圖片描述

df.groupby('season').aqi.mean().sort_values()
season
Summer     71.911104
Autumn     76.040072
Spring     82.730394
Winter    101.647808
Name: aqi, dtype: float64

全國空氣質量冬季時最差,平均AQI爲101.6(輕度污染),夏季時最好,平均AQI爲71.9(良好)。

發佈了14 篇原創文章 · 獲贊 2 · 訪問量 326
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章