阅读提示
空气质量(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>
skew的定义
偏度(skewness),是统计数据分布偏斜方向和程度的度量,是统计数据分布非对称程度的数字特征。偏度(Skewness)亦称偏态、偏态系数。
表征概率分布密度曲线相对于平均值不对称程度的特征数。直观看来就是密度函数曲线尾部的相对长度。
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>
# 当数据比较大的时候,可以使用boxenplot(信值图)
plt.figure(figsize=(15, 10))
plt.xticks(rotation=45, fontsize=15)
sns.boxenplot(data=data)
<matplotlib.axes._subplots.AxesSubplot at 0x139f3bbc3c8>
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>
现在我们已经得到了剔除离群值之后的图像了
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>
观察图像可得出,空气质量最好的五个城市为:
韶关市、南平市、梅州市、基隆市、三明市
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>
观察图像可得出,空气质量最差的五个城市为:
北京市、朝阳市、保定市、锦州市、焦作市
总结
至此,由于篇幅原因,本文的分析就先告一段落了,在后续的文章中会继续对数据进行挖掘与分析,比如挖掘全国各地城市的空气质量、沿海城市是否优于内陆城市等等…会使用到正态分布、t检验、散点图、箱线图等多种可视化手段来进行深度挖掘与分析,感谢各位读者的阅读。