一.选题背景
空气质量(Air quality)是依据空气中污染物浓度的高低来判断的,其好坏反映了空气污染程度。空气污染是一个复杂的现象,在特定时间和地点空气污染物浓度受到许多因素影响。空气质量不达标的危害有很多,例如1、危害人体:当大气中污染物的浓度很高时,会造成人体急性污染中毒,或使病状恶化,甚至在几天内夺去几千人的生命。2、对植物的危害:当污染物浓度很高时,会对植物产生急性危害,使植物叶表面产生伤斑,导致枝叶枯萎脱落;3、影响气候:空气污染会减少阳光到达地面的太阳辐射量,增加大气降水量,同时也会增加下酸雨的机率,而酸雨能使大片森林和农作物毁坏,能使纸品、纺织品、皮革制品等腐蚀破碎,能使金属的防锈涂料变质而降低保护作用,还会腐蚀污染建筑物。
二.大数据分析设计方案
从网址中爬取完数据后,在python环境中导入pandas、plotly等库进行数据整理,经过数据清洗,检查数据等,然后进行可视化处理,找到空气质量的关系完成数据分析。
数据来源:'http://tianqihoubao.com/aqi/beijing-{year}0{month}.html'
思路:对数据集进行分析,进行数据清洗,根据所需内容对数据进行可视化最后得到图像并分析结果。
三.大数据分析步骤
爬取网站生成csv文件的过程。
import csv import random import time import pandas as pd import requests from bs4 import BeautifulSoup import matplotlib.pyplot as plt plt.rcParams["font.sans-serif"] = ["SimHei"] plt.rcParams["axes.unicode_minus"] = False class Spider(object): def __init__(self): pass def get_data_and_save(self): with open('data.csv', 'w', encoding='utf-8', newline='') as f: csv_writer = csv.writer(f) csv_writer.writerow(['日期', '质量等级', 'AQI指数', '当天AQI排名', 'PM2.5', 'PM10', 'So2', 'No2', 'Co', 'O3']) years = [2020, 2021, 2022] #2020年到2022年 months = range(1, 13) #1月到12月 for year in years: for month in months: if month < 10: url = f'http://tianqihoubao.com/aqi/beijing-{year}0{month}.html' else: url = f'http://tianqihoubao.com/aqi/beijing-{year}{month}.html' res = requests.get(url).text soup = BeautifulSoup(res, 'html.parser') for attr in soup.find_all('tr')[1:]: one_day_data = list() for index in range(0, 10): one_day_data.append(attr.find_all('td')[index].get_text().strip()) csv_writer.writerow(one_day_data) time.sleep(2 + random.random()) print(year, month) def drawing(self): csv_df = pd.read_csv('data.csv', encoding='GBK') csv_df['日期'] = pd.to_datetime(csv_df['日期']) csv_df.index = csv_df['日期'] del csv_df['日期'] str_data = '2020-01-01' end_data = '2020-01-31' new_split_df = csv_df[str_data:end_data] values_count = new_split_df['质量等级'].value_counts().items() total = new_split_df['质量等级'].value_counts().tolist() label = new_split_df['质量等级'].value_counts().index explode = [0.01 for i in range(len(total))] fig, axes = plt.subplots(3, 1, figsize=(10, 8)) if __name__ == '__main__': spider = Spider() # 获取数据,保存数据 spider.get_data_and_save() # 画分析图 spider.drawing()
数据清洗
①导入相应模块以及数据集
import pandas as pd import numpy as np import seaborn as sns import matplotlib.pyplot as plt df=pd.read_csv('data.csv') df
②处理缺失值
发现无缺失值
③重复值处理
import pandas as pd import numpy as np import seaborn as sns import matplotlib.pyplot as plt df=pd.read_csv('data.csv') #重复值处理 df=df.drop_duplicates() df
④清除空值
import pandas as pd import numpy as np import seaborn as sns import matplotlib.pyplot as plt df=pd.read_csv('data.csv') #清除空值 datas = df.dropna() display(datas)
⑤查看是有有true
import pandas as pd import numpy as np import seaborn as sns import matplotlib.pyplot as plt df=pd.read_csv('data.csv') df.isna().any() #s是否有true值
数据分析与数据可视化:
字典统计法:
# Author:xueling # 先打开一篇我们要统计的文章,并读取内容 f = open(r'data.csv', 'r', encoding='utf-8') article = f.read() # 建立一个空字典来存储统计结果 d = {} # 遍历整篇文章 for i in article: d[i] = d.get(i,0) + 1 # 字频统计 # 在此基础上我们还可以做一个排序: ls = sorted(list(d.items()), key= lambda x:x[1], reverse=True) print(d) f.close()
哈希表统计法
# Author:xueling # 在colletions 导入哈希表的包 from collections import defaultdict # 打开一个要统计的文件 f = open(r'data.csv', 'r', encoding='utf-8') article = f.read() # d是通过defaultdict生成的一个哈希表,其中value我们给int型的数据类型,来记录字符数 d = defaultdict(int) # article里每一个字我们把它当做哈希表里的key,每有一个字就给value + 1,value默认值就是0 for key in article: d[key] += 1 print(d)
数据分类
绘制AQI与PM2.5的关系散点图
import pandas as pd import numpy as np import seaborn as sns import matplotlib.pyplot as plt df=pd.read_csv('data.csv') #绘制 aqi 和 pm2.5 的关系散点图 # 设置图像尺寸 plt.figure(figsize=(15, 10)) # 绘制散点图,横坐标为aqi数据的第二列,纵坐标为aqi数据的第四列 plt.scatter(df[df.columns[1]], df[df.columns[3]]) # 设置横轴标签为'AQI',字体大小为20 plt.xlabel('空气等级', fontsize=20) # 设置纵轴标签为'PM2.5',字体大小为20 plt.ylabel('AQI', fontsize=20) # 设置图像标题为'AQI和PM2.5的关系散点图',字体大小为25 plt.title('空气质量等级分类散点图', fontsize=25) # 显示图像 plt.show()
绘制空气等级质量的单变量分布图
import pandas as pd import numpy as np import seaborn as sns import seaborn as sn import matplotlib.pyplot as plt df=pd.read_csv('data.csv') # 绘制空气质量等级单变量分布图 # 绘制以第三列为 x 轴,数据来源为 aqi 的计数图 sn.countplot(x=df.columns[2], data=df) # 设置标题为“空气质量等级单变量分布图” plt.title("空气质量等级单变量分布图") # 设置 x 轴标签为“质量等级” plt.xlabel("质量等级") # 设置 y 轴标签为“aqi” plt.ylabel("aqi") # 显示图像 plt.show()
可知,AQI指数越高,空气质量越差。
制作2020-2022年空气质量饼图
import numpy as np import pandas as pd import matplotlib import matplotlib.pyplot as plt # 读文件,去无用字段 bj_date = pd.read_csv('data.csv') # print(bj_date.head(30)) # 数据清洗 #bj_date.drop(bj_date[np.isnan(bj_date['PM_US Post'])].index, inplace=True) # 空气质量定级 def get_level(AQI指数): if AQI指数 < 35: return '优' elif AQI指数 < 75: return '良' elif AQI指数 < 150: return '轻度污染' elif AQI指数 < 250: return '中度污染' elif AQI指数 >= 250: return '高度污染' # 给原始数据添加新列表level bj_date.loc[:, 'level'] = bj_date['AQI指数'].apply(get_level) print(bj_date) # 统计各种空气质量的比列 bj_level=bj_date.groupby(['level']).size() / len(bj_date) print(bj_level) #画图 matplotlib.rcParams['font.sans-serif'] = 'SimHei' l=['中度污染','优','良','轻度污染','高度污染'] plt.pie(bj_level,labels=l,autopct='%.2f%%') plt.title('北京空气质量指数') plt.show()
这三年中,优良空气占比高。
绘制PM2.5与AQI的线性回归图
import pandas as pd import numpy as np import seaborn as sns import seaborn as sn import matplotlib.pyplot as plt df=pd.read_csv('data.csv') # 绘制PM2.5与AQI的线性回归拟合图 # 调用seaborn库的regplot函数,将PM2.5含量(ppm)作为x轴,AQI作为y轴,数据源为aqi sn.regplot(x='PM2.5', y='AQI指数', data=df) # 设定图表标题为 'PM2.5与AQI的线性回归拟合图' plt.title('PM2.5与AQI的线性回归拟合图') # 设定图表x轴标签为'PM2.5含量(ppm)' plt.xlabel('PM2.5含量(ppm)') # 设定图表y轴标签为'AQI' plt.ylabel('AQI') # 显示图表 plt.show()
可以看出,AQI排放量与PM2.5成正比,AQI排放越高PM2.5指数越大,空气越差。
绘制各污染物之间的特征相关性热力分布图
import pandas as pd import numpy as np import seaborn as sns import seaborn as sn import matplotlib.pyplot as plt df=pd.read_csv('data.csv') # 绘制特征相关性热力图 # 设置画布大小 plt.figure(figsize=(17, 14)) # 计算相关系数并赋值给变量 corr corr = df[['AQI指数', 'PM2.5', 'PM10', 'So2', 'Co', 'No2', 'O3']].corr() # 以热图的形式展示相关性,并用蓝红色调表示,同时在每个方格中显示数值,并设置线宽为1 sn.heatmap(corr, cmap='RdBu_r', annot=True, linewidths=1) # 设置热图的标题,并设置字体大小为25 plt.title("各污染物之间的特征相关性热力分布图", fontsize=25) # 设置x轴标签字体大小为15 plt.xticks(fontsize=15) # 设置y轴标签字体大小为15 plt.yticks(fontsize=15) # 展示画布 plt.show()
绘制每日So2与AQI排放量的条形图
# 打开清洗后的数据文件'data.csv' import pandas as pd df_new = pd.read_csv('data.csv') df_new import matplotlib.pyplot as plt #导入matplotlib库中的pyplot模块,pyplot是用于创建图表的主要函数 df_new['当天AQI排名'].value_counts().nlargest(10).plot.bar(figsize=(14,6),fontsize= 13) plt.title('柱形图',fontsize= 20) plt.xlabel('AQI',fontsize= 16) plt.xticks(rotation=0) #设置X轴刻度标签的旋转角度。xticks是指X轴上的刻度,rotation参数指定刻度标签的旋转度数,0表示不旋转。若刻度标签内容过长,旋转角度可以调整为其他角度,以便更好地展示文本。 plt.ylabel('So2',fontsize= 16) plt.legend() #显示标签 plt.rcParams['font.sans-serif'] = ['SimHei'] #设置显示中文字符的字体 plt.grid() #显示网格线 plt.show() #s显示图形,
So2排放量越高,AQI指数越大。
总代码:
1 import csv 2 import random 3 import time 4 import pandas as pd 5 import requests 6 from bs4 import BeautifulSoup 7 import matplotlib.pyplot as plt 8 import numpy as np 9 import seaborn as sns 10 import jieba
11 #导入对应包 12 plt.rcParams["font.sans-serif"] = ["SimHei"] 13 plt.rcParams["axes.unicode_minus"] = False 14 15 16 class Spider(object): 17 def __init__(self): 18 pass 19 20 def get_data_and_save(self): 21 with open('data.csv', 'w', encoding='utf-8', newline='') as f: 22 csv_writer = csv.writer(f) 23 csv_writer.writerow(['日期', '质量等级', 'AQI指数', '当天AQI排名', 'PM2.5', 'PM10', 'So2', 'No2', 'Co', 'O3']) 24 years = [2020, 2021, 2022] 25 #2020年到2022年 26 months = range(1, 13) 27 #1月到12月 28 for year in years: 29 for month in months: 30 if month < 10: 31 url = f'http://tianqihoubao.com/aqi/beijing-{year}0{month}.html' 32 else: 33 url = f'http://tianqihoubao.com/aqi/beijing-{year}{month}.html' 34 res = requests.get(url).text 35 soup = BeautifulSoup(res, 'html.parser') 36 for attr in soup.find_all('tr')[1:]: 37 one_day_data = list() 38 for index in range(0, 10): 39 one_day_data.append(attr.find_all('td')[index].get_text().strip()) 40 csv_writer.writerow(one_day_data) 41 time.sleep(2 + random.random()) 42 print(year, month) 43 44 def drawing(self): 45 csv_df = pd.read_csv('data.csv', encoding='GBK') 46 csv_df['日期'] = pd.to_datetime(csv_df['日期']) 47 csv_df.index = csv_df['日期'] 48 del csv_df['日期'] 49 50 str_data = '2020-01-01' 51 end_data = '2020-01-31' 52 new_split_df = csv_df[str_data:end_data] 53 values_count = new_split_df['质量等级'].value_counts().items() 54 total = new_split_df['质量等级'].value_counts().tolist() 55 label = new_split_df['质量等级'].value_counts().index 56 explode = [0.01 for i in range(len(total))] 57 fig, axes = plt.subplots(3, 1, figsize=(10, 8)) 58 59 60 61 if __name__ == '__main__': 62 spider = Spider() 63 # 获取数据,保存数据 64 spider.get_data_and_save() 65 # 画分析图 66 spider.drawing() 67 df=pd.read_csv('data.csv') 68 df 69 #导出CSV 70 71 #处理缺失值 72 df.isnull().sum() 73 74 df=pd.read_csv('data.csv') 75 #重复值处理 76 df=df.drop_duplicates() 77 df 78 79 import matplotlib.pyplot as plt 80 df=pd.read_csv('data.csv') 81 df.isna().any() 82 #判断是否有TRUE 83 84 import matplotlib.pyplot as plt 85 df=pd.read_csv('data.csv') 86 #清除空值 87 datas = df.dropna() 88 display(datas) 89 90 df=pd.read_csv('data.csv') 91 #绘制 aqi 和 pm2.5 的关系散点图 92 # 设置图像尺寸 93 plt.figure(figsize=(15, 10)) 94 # 绘制散点图,横坐标为aqi数据的第二列,纵坐标为aqi数据的第四列 95 plt.scatter(df[df.columns[1]], df[df.columns[3]]) 96 # 设置横轴标签为'AQI',字体大小为20 97 plt.xlabel('空气等级', fontsize=20) 98 # 设置纵轴标签为'PM2.5',字体大小为20 99 plt.ylabel('AQI', fontsize=20) 100 # 设置图像标题为'AQI和PM2.5的关系散点图',字体大小为25 101 plt.title('空气质量等级分类散点图', fontsize=25) 102 # 显示图像 103 plt.show() 104 105 df=pd.read_csv('data.csv') 106 # 绘制空气质量等级单变量分布图 107 # 绘制以第三列为 x 轴,数据来源为 aqi 的计数图 108 sn.countplot(x=df.columns[2], data=df) 109 # 设置标题为“空气质量等级单变量分布图” 110 plt.title("空气质量等级单变量分布图") 111 # 设置 x 轴标签为“质量等级” 112 plt.xlabel("质量等级") 113 # 设置 y 轴标签为“aqi” 114 plt.ylabel("aqi") 115 # 显示图像 116 plt.show() 117 118 df=pd.read_csv('data.csv') 119 # 绘制PM2.5与AQI的线性回归拟合图 120 # 调用seaborn库的regplot函数,将PM2.5含量(ppm)作为x轴,AQI作为y轴,数据源为aqi 121 sn.regplot(x='PM2.5', y='AQI指数', data=df) 122 # 设定图表标题为 'PM2.5与AQI的线性回归拟合图' 123 plt.title('PM2.5与AQI的线性回归拟合图') 124 # 设定图表x轴标签为'PM2.5含量(ppm)' 125 plt.xlabel('PM2.5含量(ppm)') 126 # 设定图表y轴标签为'AQI' 127 plt.ylabel('AQI') 128 # 显示图表 129 plt.show() 130 131 df=pd.read_csv('data.csv') 132 # 绘制特征相关性热力图 133 # 设置画布大小 134 plt.figure(figsize=(17, 14)) 135 # 计算相关系数并赋值给变量 corr 136 corr = df[['AQI指数', 'PM2.5', 'PM10', 'So2', 'Co', 'No2', 'O3']].corr() 137 # 以热图的形式展示相关性,并用蓝红色调表示,同时在每个方格中显示数值,并设置线宽为1 138 sn.heatmap(corr, cmap='RdBu_r', annot=True, linewidths=1) 139 # 设置热图的标题,并设置字体大小为25 140 plt.title("各污染物之间的特征相关性热力分布图", fontsize=25) 141 # 设置x轴标签字体大小为15 142 plt.xticks(fontsize=15) 143 # 设置y轴标签字体大小为15 144 plt.yticks(fontsize=15) 145 # 展示画布 146 plt.show() 147 148 # Author:xueling 149 # 先打开一篇我们要统计的文章,并读取内容 150 f = open(r'data.csv', 'r', encoding='utf-8') 151 article = f.read() 152 # 建立一个空字典来存储统计结果 153 d = {} 154 # 遍历整篇文章 155 for i in article: 156 d[i] = d.get(i,0) + 1 157 # 字频统计 158 # 在此基础上我们还可以做一个排序: 159 ls = sorted(list(d.items()), key= lambda x:x[1], reverse=True) 160 print(d) 161 f.close() 162 #字典统计方法 163 # Author:xueling 164 # 在colletions 导入哈希表的包 165 from collections import defaultdict 166 # 打开一个要统计的文件 167 f = open(r'data.csv', 'r', encoding='utf-8') 168 article = f.read() 169 # d是通过defaultdict生成的一个哈希表,其中value我们给int型的数据类型,来记录字符数 170 d = defaultdict(int) 171 # article里每一个字我们把它当做哈希表里的key,每有一个字就给value + 1,value默认值就是0 172 for key in article: 173 d[key] += 1 174 print(d) 175 #哈希表统计方法 176 177 # 读文件,去无用字段 178 bj_date = pd.read_csv('data.csv') 179 # print(bj_date.head(30)) 180 # 数据清洗 181 #bj_date.drop(bj_date[np.isnan(bj_date['PM_US Post'])].index, inplace=True) 182 183 184 # 空气质量定级 185 def get_level(AQI指数): 186 if AQI指数 < 35: 187 return '优' 188 elif AQI指数 < 75: 189 return '良' 190 elif AQI指数 < 150: 191 return '轻度污染' 192 elif AQI指数 < 250: 193 return '中度污染' 194 elif AQI指数 >= 250: 195 return '高度污染' 196 197 198 # 给原始数据添加新列表level 199 bj_date.loc[:, 'level'] = bj_date['AQI指数'].apply(get_level) 200 print(bj_date) 201 # 统计各种空气质量的比列 202 bj_level=bj_date.groupby(['level']).size() / len(bj_date) 203 print(bj_level) 204 #画图 205 matplotlib.rcParams['font.sans-serif'] = 'SimHei' 206 l=['中度污染','优','良','轻度污染','高度污染'] 207 plt.pie(bj_level,labels=l,autopct='%.2f%%') 208 plt.title('北京空气质量指数') 209 plt.show() 210 211 # 打开清洗后的数据文件'data.csv' 212 import pandas as pd 213 df_new = pd.read_csv('data.csv') 214 df_new 215 import matplotlib.pyplot as plt 216 #导入matplotlib库中的pyplot模块,pyplot是用于创建图表的主要函数 217 df_new['当天AQI排名'].value_counts().nlargest(10).plot.bar(figsize=(14,6),fontsize= 13) 218 plt.title('柱形图',fontsize= 20) 219 plt.xlabel('AQI',fontsize= 16) 220 plt.xticks(rotation=0) 221 #设置X轴刻度标签的旋转角度。xticks是指X轴上的刻度,rotation参数指定刻度标签的旋转度数,0表示不旋转。若刻度标签内容过长,旋转角度可以调整为其他角度,以便更好地展示文本。 222 plt.ylabel('So2',fontsize= 16) 223 plt.legend() 224 #显示标签 225 plt.rcParams['font.sans-serif'] = ['SimHei'] 226 #设置显示中文字符的字体 227 plt.grid() 228 #显示网格线 229 plt.show() 230 #s显示图形,
总结:
1.pm2.5,pm10,so2,no2,co,o3等有毒气体对AQI指数的影响,有毒气体排放越大,AQI指数越大,AQI指数越大,空气质量越差。
2.我们应爱护环境,减少有毒气体的排放,坚持绿色发展。
改进的建议包括:
增加更多的数据源,以获得更全面和准确的数据,可以提却更多的字段信息,从不同角度去分析“空气污染程度”的普及程度。
进一步优化爬虫程序的效率和稳定性。
进一步深入数据分析和建模,例如使用机器学习算法进行情感分析或预测模型的构建。
增加更多的数据可视化方法和图表类型,以更好地展示数据和结论。
要对所获取的文本进行更加精确的分词以及进行聚类,使所得到的分词更具有主题性。
通过不断改进和完善,可以使网络爬虫程序更具实用性和可靠性,并为空气污染相关的数据分析提供更有价值的见解。