Python数据分析之空气质量(AQI)分析与预测 1

阅读提示

空气质量(Air quality) 是依据空气中污染物浓度的高低来判断的,其好坏反映了空气污染程度。随着科技与工业水平的进步,空气质量每况日下,现在已经称为了严重的全球问题,由此诞生的PM2.5、APCE蓝等网红热词不禁引人深思,本文将通过Python数据分析手段对数据深入挖掘,分析各地空气质量


在这里插入图片描述

1、什么是AQI

AQI(Air Quality Index),指空气质量指数,用来衡量空气清洁和污染的程度。AQI值越小,说明空气质量越好。而近年来空气污染日益严重,AQI指数理所应当的受到了人们的重视。

2、任务目的

  • 判断哪些城市的空气质量较好/较差(描述性统计分析)

  • 空气质量在地理位置上的分布是否有规律性?(描述性统计分析)

  • 临海城市的空气质量是否和内陆环境有区别(推断统计分析)

  • 空气质量主要受到哪些因素的影响?(相关系数分析)

  • 全国的空气质量处于哪种水平?(区间估计)

  • 怎样预测一个城市的空气质量?(统计建模)

3、数据集描述

来源:2015年空气质量数据集,包含了全国主要城市的相关数据和空气质量指数

4、代码实现

4.1 库的导入

import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import warnings
import seaborn as sns

sns.set(style = "darkgrid", font = "SimHei", rc = {"axes.unicode_minus" : False })
warnings.filterwarnings("ignore")

4.2 加载数据集

data = pd.read_csv("data.csv")
print(data.shape)
data.head()
(325, 12)
City AQI Precipitation GDP Temperature Longitude Latitude Altitude PopulationDensity Coastal GreenCoverageRate Incineration(10,000ton)
0 Ngawa Prefecture 23 665.1 271.13 8.200000 102.224650 31.899410 2617.0 11 0 36.00 23.00
1 Aksu City 137 80.4 610.00 12.276712 80.263380 41.167540 1108.0 6547 0 33.94 23.00
2 Alxa League 85 150.0 322.58 24.200000 105.728950 38.851920 1673.0 1 0 36.00 23.00
3 Ngari 28 74.2 37.40 1.000000 80.105800 32.501110 4280.0 1 0 36.00 23.00
4 Anqin City 79 2127.8 1613.20 17.291781 117.034431 30.512646 13.0 2271 0 45.80 27.48

4.3 数据清洗

4.3.1 缺失值处理

data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 325 entries, 0 to 324
Data columns (total 12 columns):
 #   Column                   Non-Null Count  Dtype  
---  ------                   --------------  -----  
 0   City                     325 non-null    object 
 1   AQI                      325 non-null    int64  
 2   Precipitation            321 non-null    float64
 3   GDP                      325 non-null    float64
 4   Temperature              325 non-null    float64
 5   Longitude                325 non-null    float64
 6   Latitude                 325 non-null    float64
 7   Altitude                 325 non-null    float64
 8   PopulationDensity        325 non-null    int64  
 9   Coastal                  325 non-null    int64  
 10  GreenCoverageRate        325 non-null    float64
 11  Incineration(10,000ton)  325 non-null    float64
dtypes: float64(8), int64(3), object(1)
memory usage: 30.6+ KB

在这里可以看到 Precipitation 降雨量有4个缺失值

问题:
如果降雨量这一列中,有100条记录存在缺失值,哪种方法处理起来更好?

A. 删除缺失值所在的行

B. 使用均值进行填充

C. 使用中值进行填充

D. B或C

E. 无法判断

print(data["Precipitation"].skew())
sns.distplot(data["Precipitation"].dropna())
0.27360760671177387





<matplotlib.axes._subplots.AxesSubplot at 0x139f3968e10>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-djmD6ksh-1583500114541)(output_14_2.png)]

skew的定义

偏度(skewness),是统计数据分布偏斜方向和程度的度量,是统计数据分布非对称程度的数字特征。偏度(Skewness)亦称偏态、偏态系数。

表征概率分布密度曲线相对于平均值不对称程度的特征数。直观看来就是密度函数曲线尾部的相对长度。
p = 1 1 + e z p = \frac{1}{1+e^{z}}

data.fillna({"Precipitation" : data["Precipitation"].median()}, inplace=True)

4.3.2 异常值的处理

  • 通过describe查看数值信息
  • 可以使用箱线图观察数据分布
#data.describe()

通过箱线图的呈现可以很容易的观测到离群值

plt.figure(figsize=(15, 10))
plt.xticks(rotation=45, fontsize=15)
sns.boxplot(data=data)
<matplotlib.axes._subplots.AxesSubplot at 0x139f39a3c88>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RHHhoG6H-1583500114543)(output_20_1.png)]

# 当数据比较大的时候,可以使用boxenplot(信值图)
plt.figure(figsize=(15, 10))
plt.xticks(rotation=45, fontsize=15)
sns.boxenplot(data=data)
<matplotlib.axes._subplots.AxesSubplot at 0x139f3bbc3c8>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qigvGfda-1583500114543)(output_21_1.png)]

boxplot和boxenplot的区别

首先是boxplot()

seaborn.boxplot(x=None, y=None, hue=None, data=None, order=None, hue_order=None, 
                orient=None, color=None, palette=None, saturation=0.75, width=0.8, dodge=True, fliersize=5, 
                linewidth=None, whis=1.5, notch=False, ax=None, **kwargs)

参数详解:

  • x, y, hue:数据或向量数据中的变量名称,用于绘制长格式数据的输入。

  • data:DataFrame,数组,数组列表,用于绘图的数据集。如果x和y都缺失,那么数据将被视为宽格式。否则数据被视为长格式。

  • order, hue_order:字符串列表,控制分类变量(对应的条形图)的绘制顺序,若缺失则从数据中推断分类变量的顺序。

  • orient:“v”或“h”,控制绘图的方向(垂直或水平)。这通常是从输入变量的 dtype 推断出来的,但是当“分类”变量为数值型或绘制宽格式数据时可用于指定绘图的方向。

  • color:matplotlib颜色,所有元素的颜色,或渐变调色板的种子颜色。

  • palette:调色板名称,列表或字典,用于hue变量的不同级别的颜色。可以从color_palette()得到一些解释,或者将色调级别映射到matplotlib颜色的字典。

  • saturation:float,控制用于绘制颜色的原始饱和度的比例。通常大幅填充在轻微不饱和的颜色下看起来更好,如果您希望绘图颜色与输入颜色规格完美匹配可将其设置为1。

  • width:float,不使用色调嵌套时完整元素的宽度,或主要分组变量一个级别的所有元素的宽度。

  • dodge:bool,使用色调嵌套时,元素是否应沿分类轴移动。

  • fliersize:float,用于表示异常值观察的标记的大小。

  • linewidth:float,构图元素的灰线宽度。

  • whis:float,控制在超过高低四分位数时 IQR (四分位间距)的比例,因此需要延长绘制的触须线段。超出此范围的点将被识别为异常值。

  • notch:boolean,是否使矩形框“凹陷”以指示中位数的置信区间。还可以通过plt.boxplot的一些参数来控制

  • ax:matplotlib轴,绘图时使用的 Axes 轴对象,否则使用当前 Axes 轴对象

  • kwargs:键值映射,其他在绘图时传给plt.boxplot的参数

boxenplit()

seaborn.boxenplot(x=None, y=None, hue=None, data=None, order=None, hue_order=None, orient=None,
                  color=None, palette=None, saturation=0.75, width=0.8, dodge=True,
                  k_depth='proportion',linewidth=None, scale='exponential', outlier_prop=None,
                  ax=None, **kwargs)

boxenplot()的参数大体上与boxplot()差不多,但是多了三个不同的参数

  • k_depth:“proportion” 或 “tukey” 或 “trustworthy”,通过增大百分比的粒度控制绘制的盒形图数目。每个参数代表利用不同的统计特性对异常值的数量做出不同的假设。

  • scale:“linear” 或 “exponential” 或 “area”,用于控制增强箱型图宽度的方法。所有参数都会给显示效果造成影响。 “linear” 通过恒定的线性因子减小宽度,“exponential” 使用未覆盖的数据的比例调整宽度, “area” 与所覆盖的数据的百分比成比例。

  • outlier_prop:float,被认为是异常值的数据比例。与 k_depth 结合使用以确定要绘制的百分位数。默认值为 0.007 作为异常值的比例。该参数取值应在[0,1]范围内。

t = data.copy()
for k in t:
    if pd.api.types.is_numeric_dtype(t[k]):
        o = t[k].describe()
        IQR = o["75%"] - o["25%"]
        lower = o["25%"] - 1.5 * IQR
        upper = o["75%"] + 1.5 * IQR
        t[k][t[k] < lower] = lower
        t[k][t[k] > upper] = upper
plt.figure(figsize=(15, 4))
plt.xticks(rotation=45, fontsize=15)
sns.boxplot(data=t)
<matplotlib.axes._subplots.AxesSubplot at 0x139f5bd1978>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l01qI7dm-1583500114544)(output_24_1.png)]

现在我们已经得到了剔除离群值之后的图像了

4.3.3 重复值处理

  • 可以使用duplicated()来检查重复,并通过keep参数进行调整
  • 找到重复值后再用drop_duplicate()进行重复值剔除
data.duplicated().sum()
2
data[data.duplicated()] # 查看重复值
City AQI Precipitation GDP Temperature Longitude Latitude Altitude PopulationDensity Coastal GreenCoverageRate Incineration(10,000ton)
109 Baoding City 220 566.9 2757.80 13.258904 115.500183 38.857071 17.2 4565 0 30.96 49.27
218 Luohe City 85 831.0 992.85 15.704110 114.041092 33.572510 62.0 5283 0 34.39 22.00
data.drop_duplicates(inplace=True)

5、 数据分析

数据分析是呈现数据样本、提供分析结果最为根本,也是最为关键的一步,这里我们将通过柱状图观测空气质量的好坏程度。

5.1 分析空气质量最好/最差的五个城市

分析的结果可用来对选择旅游地点做参考

5.1.1 空气质量最好的5个城市

t = data[["City", "AQI"]].sort_values("AQI")
display(t.iloc[:5])
plt.xticks(rotation=40,fontsize=15)
sns.barplot(x="City", y="AQI", data=t.iloc[:5])
City AQI
204 Shaoguan City 12
163 Nanping City 12
154 Meizhou City 12
91 Keelung City 13
195 Sanming City 13
<matplotlib.axes._subplots.AxesSubplot at 0x139f839e6d8>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sdysEruA-1583500114544)(output_31_2.png)]

观察图像可得出,空气质量最好的五个城市为:
韶关市、南平市、梅州市、基隆市、三明市

5.1.2 空气质量最差的5个城市

display(t.iloc[-5:])
City AQI
105 Jiaozuo City 199
112 Jinzhou City 202
13 Baoding City 220
26 Chaoyang City 224
16 Beijing City 296
plt.xticks(rotation=40, fontsize=15)
sns.barplot(x="City", y="AQI", data=t.iloc[-5:])
<matplotlib.axes._subplots.AxesSubplot at 0x139f8df00b8>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZpTSqrsA-1583500114544)(output_35_1.png)]

观察图像可得出,空气质量最差的五个城市为:
北京市、朝阳市、保定市、锦州市、焦作市




总结

至此,由于篇幅原因,本文的分析就先告一段落了,在后续的文章中会继续对数据进行挖掘与分析,比如挖掘全国各地城市的空气质量沿海城市是否优于内陆城市等等…会使用到正态分布、t检验、散点图、箱线图等多种可视化手段来进行深度挖掘与分析,感谢各位读者的阅读。

发布了29 篇原创文章 · 获赞 379 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43656359/article/details/104704396
今日推荐