人生这条路很长,未来如星辰大海般璀璨,不必踟躇于过去的半亩方塘。
真正的优秀不是别人逼出来的,而是自己和自己死磕。 ------ Gaowaly
`

python机器学习(第一章 Python机器学习基础)

第一章 Python机器学习基础

基础:

Python官网:https://www.python.org/doc/;

历史版本下载与维护信息:https://www.python.org/downloads/

Anaconda官网: https://www.anaconda.com/

清华镜像下载:https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/

Anaconda,方便包管理;内嵌了Python、Pycharm、Jupyter Notebook、Spyder等。

 

基础-Anaconda

 

 

 

基础-Jupyter Notebook

 

 

 

基础

Python第三方库引用

import pandas as pd
from tensorflow import keras
from tensorflow.keras.models import load_model, Sequential

一些典型、著名的第三方库:NumPy、Pandas、SciPy、Matplotlib、Scikit-learn,广泛应用:科学计算、可视化、机器方面等。

python==3.8.8
numpy==1.20.1
matplotlib==3.3.4
pandas==1.2.4
pandas_profiling==2.12.0
scikit-learn==0.24.1
tensorflow==2.8.2

一、NumPy

NumPy是一种开源的高性能科学计算和数据分析的基础包,支持大量的维度数组与矩阵运算。

numpy中最核心的数据结构是ndarray

NumPy 要求数据集中各变量的类型相同。

ndarray.ndim - 数组的轴(维度)的个数。

在Python中,维度的数量被称为rank。

ndarray.shape - 数组的维度。这是一个整数的元组,表示每个维度中数组的大小。对于有 n 行和 m 列的矩阵,shape 将是 (n,m)。

因此,shape 元组的长度就是rank或维度的个数 ndim。

 

ndarray.size - 数组元素的总数。这等于 shape 的元素的乘积。

ndarray.dtype - 一个描述数组中元素类型的对象。可以使用标准的Python类型创建或指定dtype。另外NumPy提供它自己的类型。例如numpy.int32、numpy.int16和numpy.float64。

ndarray.itemsize - 数组中每个元素的字节大小。例如,元素为 float64 类型的数组的 itemsize 为8(=64/8),而 complex32 类型的数组的 itemsize 为4(=32/8)。它等于 ndarray.dtype.itemsize 。

1、np-数组创建、访问

import numpy as np
data=np.array([1,2,3,4,5,6,7,8,9])

print('Numpy的1维数组:\n{0}'.format(data))
print('数据类型:%s'%data.dtype)
print('1维数组中各元素扩大10倍:\n{0}'.format(data*10))
print('访问第2个元素:{0}'.format(data[1]))
data=np.array([[1,3,5,7,9],[2,4,6,8,10]])
print('Numpy的2维数组:\n{0}'.format(data))
print('访问2维数组中第1行第2列元素:{0}'.format(data[0,1]))
print('访问2维数组中第1行第2至4列元素:{0}'.format(data[0,1:4]))
print('访问2维数组中第1行上的所有元素:{0}'.format(data[0,:]))

注意:

format()常见的用法:
其实就是format()后面的内容,填入大括号中(可以按位置,或者按变量)

'数字{1}{2}和{0}'.format("123",456,'789')
>>>'数字456789和123'
#这里注意有两层大括号,输出的结果只有一层大括号
'数字{{{1}{2}}}和{0}'.format("123",456,'789')
>>>'数字{456789}和123'
#允许一个参数用两次
'{1}{0}{1}岁'.format('jc',22) 
>>>'22jc22岁'
#可以通过添加关键字参数
'{name}{age}岁'.format(age=22,name='jc') 
>>>'jc22岁'

输出结果

代码说明:

(1)第2行:创建一个NumPy的1维数组。 数组中的数据元素来自Python的列表(list)。Python列表通过方括号[]和逗号将各数据元素组织在一起,是Python组织数据的最常见方式。np.array可将列表转换为NumPy的N维数组。

(2)第5行:将数组中的每个元素均扩大十倍。 NumPy的数据计算非常方便,只需通过加减乘除等算术运算符,就可完成对数组元素的统一计算,或多个数组中相同位置上元素的计算。

(3)第6行:通过指定位置编号(也称索引,从0开始编号)访问相应行位置上的元素。索引需放置在数组名后的方括号内。

(4)第7行:创建一个NumPy的2维数组,数组形状为2行5列。数组元素同样来自Python的列表。

(5)第9至11行:通过索引访问相应行列位置上的元素。对于2维数组,需给出两个索引,以逗号分割并放置在方括号内。 第1个索引指定行,第2个索引指定列。可通过冒号:指定索引范围。

data=[[1,2,3,4,5,6,7,8,9],['A','B','C','D','E','F','G','H','I’]]
print('data是Python的列表(list):\n{0}'.format(data))
MyArray1=np.array(data)
print('MyArray1是Numpy的N维数组:\n%s\nMyarray1的形状:%s'%(MyArray1,MyArray1.shape))

 

代码说明:

(1)第1行:创建名为data的2维Python列表。 可简单地将2维列表与一个二维表格相对应。表中各元素的数据类型可以不同(例如本例中的1,2,3等数值型和’A’,’B’,’C’等字符型)。每行的列数可以不同。

(2)第3行:将列表转成NumPy数组。 通过np.array将列表转成数组时,因数组要求数据类型一致,所以这里自动将数值型转换为字符型。

(3)第4行:显示数组内容和数组形状。 .shape是NumPy数组的属性之一,存储数组的行数和列数。

2、np-数组计算

MyArray2=np.arange(10)
print('MyArray2:\n{0}'.format(MyArray2))

print('MyArray2的基本描述统计量:\n均值:%f,标准差:%f,总和:%f,最大值:%f’
%(MyArray2.mean(), MyArray2.std(), MyArray2.sum(), MyArray2.max()))

print('MyArray2的累计和:{0}'.format(MyArray2.cumsum()))
print('MyArray2开平方:{0}'.format(np.sqrt(MyArray2)))

np.random.seed(123)
MyArray3=np.random.randn(10)
print('MyArray3:\n{0}'.format(MyArray3))

print('MyArray3排序结果:\n{0}'.format(np.sort(MyArray3)))
print('MyArray3四舍五入到最近整数:\n{0}'.format(np.rint(MyArray3)))

print('MyArray3各元素的正负号:{0}'.format(np.sign(MyArray3)))
print('MyArray3各元素非负数的显示"正",负数显示"负":\n{0}'.format(np.where(MyArray3>0,'','负’)))

print('MyArray2+MyArray3的结果:\n{0}'.format(MyArray2+MyArray3))

代码说明:

(1)第1行:生成数组元素是0至9的1维数组,共包含10个元素。 np.arange是NumPy中最常用函数之一,用于生成在指定范围内取值的1维数组。

(2)第3行:对数组元素计算基本描述统计量。 例如:.mean().std().sum().max()等均是数组的方法,表示分别计算数组元素的均值、标准差、总和、最大值等。

(3)第4行:利用数组方法.cumsum()计算数组元素的当前累计和。

(4)第5行:利用NumPy函数sqrt()对数组元素开平方。 除此之外,还可以对数组元素计算对数、指数、三角函数等等。

(5)第6行:利用NumPy函数seed()指定随机数种子 指定种子的目的是确保每次运行代码时,生成的随机数可以再现。否则,每次运行代码生成的随机数会不相同。

(6)第7行:生成包含10个元素且服从标准正态分布的1维数组。

(7)第9行:利用NumPy函数sort()对数组元素排序,排序结果并不覆盖原数组内容。

(8)第10行:利用NumPy函数rint()对数组元素做四舍五入。

(9)第11行:利用NumPy函数sign()求数组元素的正负符号。1表示正号,-1表示负号。

(10)第12行:利用NumPy函数where()依次对数组元素进行逻辑判读。 where()需指定判断条件(如>0),满足条件的返回第一个值(如‘正’),否则返回第二个值(如‘负’)。若省略第2和第3个参数,例如:where(Myarray3>0)将给出满足条件的元素索引号。

(11)第13行:将两个数组相同位置上的元素相加。

 输出结果:

3、np-矩阵创建与乘法

np.random.seed(123)

X=np.floor(np.random.normal(5,1,(2,5)))

Y=np.eye(5)

print('X:\n{0}'.format(X))

print('Y:\n{0}'.format(Y))

print(‘X和Y的矩阵积:\n{0}'.format(np.dot(X,Y)))

 输出结果:

 

代码说明:

(1)第2行:做两件事情,得到一个2维数组X,本质是个矩阵。 首先,利用NumPy的random.normal()函数生成2行5列的2维数组,数组元素服从均值为5,标准差为1的正态分布。然后,利用floor函数得到距各数组元素最近的最大整数。 np.floor(-0.3) == -1.0

(2)第3行:利用eye()函数生成一个大小(这里是5行5列)的单位阵Y。

(3)第6行:利用dot()函数计算矩阵X和矩阵Y(单位阵)的矩阵乘积,将得到2行5列的矩阵。

4、矩阵运算

一些重要的矩阵运算:求逆、特征值、特征向量、奇异值分解等。

from numpy.linalg import inv,svd,eig,det
X=np.random.randn(5,5)
print(X)

mat=X.T.dot(X)   # 点乘: X.T * X

print(mat)
print('矩阵mat的逆:\n{0}'.format(inv(mat)))
print('矩阵mat的行列式值:\n{0}'.format(det(mat)))
print('矩阵mat的特征值和特征向量:\n{0}'.format(eig(mat)))
print('对矩阵mat做奇异值分解:\n{0}'.format(svd(mat)))

代码说明:

(1)第1行:导入NumPy的linalg模块下有关矩阵运算的函数。

(2)第2行:生成5行5列的2维数组X(可视为一个矩阵),数组元素服从标准正态分布。

(3)第4行:X.T是X的转置,并与X相乘结果保存在mat(2维数据也即矩阵)。

(4)第6至9行:NumPy可方便计算矩阵的逆(inv)、行列式值(det)、特征值和对应的特征向量(eig)以及对矩阵进行奇异值分解(svd)等。

5、np-其他

5.1例子

a = np.arange(15).reshape(3,5)

print(a)

print(a.shape)

print(a.ndim)

print(a.dtype.name)

print(a.itemsize)

print(a.size)

输出结果:

5.2 数组创建

调用array的时候传入多个数字参数,而不是提供单个数字的列表类型作为参数。

将序列的序列转换成二维数组。

5.3 数组打印

将一维数组打印为行,将二维数据打印为矩阵,将三维数据打印为矩数组表。

 

5.4 基本操作

数组上的算术运算符会应用到 元素 级别。

乘积运算符 * 在numpy数组中按元素进行运算。

矩阵乘积可以使用@运算符(在python> = 3.5中)或dot函数或方法执行。

 

 

 

5.5 通函数

numpy提供熟悉的数学函数,例如sin,cos和exp。在numpy中,这些被称为“通函数”(ufunc)。

在numpy中,这些函数在数组上按元素进行运算,产生一个数组作为输出。

 

5.6 索引、切片和迭代

5.6.1 索引

一维的数组可以进行索引、切片和迭代操作的,就像 列表 和其他Python序列类型一样。

多维的数组每个轴可以有一个索引。这些索引以逗号​​分隔的元组给出:

 

5.6.2 切片

当提供的索引少于轴的数量时,缺失的索引被认为是完整的切片

b[i] 方括号中的表达式 i 被视为后面紧跟着 : 的多个实例,用于表示剩余轴。

numpy也允许你使用三个点写为 b[i,...]。

三个点( ... )表示产生完整索引元组所需的冒号。

例如,如果 x 是rank为5的数组(即,它具有5个轴)

x[1,2,...] 相当于 x[1,2,:,:,:],

x[...,3] 等效于 x[:,:,:,:,3]

x[4,...,5,:] 等效于 x[4,:,:,5,:]

 

 

5.6.3 迭代

 

 

对多维数组进行 迭代(Iterating) 是相对于第一个轴完成的:

 

 

如果想要对数组中的每个元素执行操作, 可以使用flat属性,该属性是数组的所有元素的迭代器

 

 

5.7 形状操纵-改变数组的形状

该reshape函数返回带有修改形状的参数,而该 ndarray.resize方法会修改数组本身。

 

 

 

如果在 reshape 操作中将 size 指定为-1,则会自动计算其他的 size 大小。

 

 

二、 Pandas

 

 

Pandas: Python data analysis,快速、便捷地处理结构化数据。

基于Numpy构建。在Numpy的N维数组上,增加了用户自定义索引,构建了一套有特色的数据组织形式。其中

1)序列(Series)对应一维数组,

2)数据框(DataFrame)对应二维表格型数据结构, 可视为多个序列 的集合

3)数据类型可以是整型、浮点数、字符串、布尔型等; 各元素的数据类型可以相同或不同。

Pandas数据框是存储机器学习数据集的常用形式。

  数据框的每一行对应着数据集中的一个样本,列对应变量。

Pandas提供了丰富的函数和方法,可方便地完成数据的预处理、加工和基本分析。

1、Pandas- Series和索引

import numpy as np
import pandas as pd
from pandas import Series,DataFrame

data=Series([1,2,3,4,5,6,7,8,9],index=['ID1','ID2','ID3','ID4','ID5','ID6','ID7','ID8','ID9’])

print('序列中的值:\n{0}'.format(data.values))
print('序列中的索引:\n{0}'.format(data.index))
print('访问序列的第1和第3上的值:\n{0}'.format(data[[0,2]]))
print('访问序列索引为ID1和ID3上的值:\n{0}'.format(data[['ID1','ID3']]))
print('判断ID1索引是否存在:%s;判断ID10索引是否存在:%s'%('ID1' in data,'ID10' in data))

代码说明:

(1)第4行:利用Pandas的函数Series()生成一个包含9个元素(取值为1至9)的序列,且指定各元素的索引名依次为ID1,ID2等。后续可通过索引访问相应元素。

(2)第5行:序列的.values属性中存储着各元素的元素值

(3)第6行:序列的.index属性中存储着各元素的索引

(4)第7行:利用索引号(从0开始)访问指定元素。应以列表形式(如[0,2])指定多个索引号。

(5)第8行:利用索引名访问指定元素。索引名应用单引号括起来。应以列表形式(如[‘ID1’,’ID3’])指定多个索引名。

(6)第9行:利用Python运算符in,判断是否存在某个索引名。若存在判断结果为True(真),否则为False(假)。True和False是Python的布尔型变量的仅有的取值。

 输出结果

 

2、Pandas- DataFrame

import pandas as pd
from pandas import Series,DataFrame

data=pd.read_excel('北京市空气质量数据.xlsx’)

print('date的类型:{0}'.format(type(data)))
print('数据框的行索引:{0}'.format(data.index))
print('数据框的列名:{0}'.format(data.columns))

print('访问AQI和PM2.5所有值:\n{0}'.format(data[['AQI','PM2.5']]))

print('访问第2至3行的AQI和PM2.5:\n{0}'.format(data.loc[1:2,['AQI','PM2.5']]))

print('访问索引1至索引2的第2和4列:\n{0}'.format(data.iloc[1:3,[1,3]]))

data.info()

代码说明:

(1)第4行:利用Python函数type()浏览对象data的类型,结果显示为数据框。

(2)第5,6行:数据框的.index.columns属性中存储着数据框的行索引列索引名。这里,行索引默认取值:0至样本量N-1。列索引名默认为数据文件中第一行的变量名。

(3)第7行:利用列索引名访问指定变量。多个列索引名应以列表形式放在方括号中([‘AQI’,’PM2.5’])。

(4)第8行:利用数据框的.loc属性访问指定行索引和变量名上的元素。 注意:数据框对应二维表格,应给两个索引。loc右闭

(5)第9行:利用数据框的.iloc属性访问指定行索引和列索引号上的元素。 注意:使用行索引时冒号:后的行不包括在内. iloc右开

(6)第10行:利用数据框的info()方法显示数据框的行索引、列索引以及数据类型等信息。

运行结果:

 

3、Pandas- 数据加工处理

 

Pandas具有强大的数据加工处理能力。数据集合并缺失值判断插补功能。

import numpy as np
import pandas as pd
from pandas import Series, DataFrame

df1=DataFrame({'key':['a','d','c','a','b','d','c'],'var1':range(7)})
df2=DataFrame({'key':['a','b','c','c'],'var2':[0,1,2,2]})

运行结果:

df=pd.merge(df1, df2, on='key',  how='outer')

df_df = pd.merge(df1, df2, on='key',  how='inner')

df.iloc[0,2]=np.NaN
df.iloc[5,1]=np.NaN
print('合并后的数据:\n{0}'.format(df))

df=df.drop_duplicates()
print('删除重复数据行后的数据:\n{0}'.format(df))

print('判断是否为缺失值:\n{0}'.format(df.isnull()))
print('判断是否不为缺失值:\n{0}'.format(df.notnull()))
print('删除缺失值后的数据:\n{0}'.format(df.dropna()))

fill_value=df[['var1','var2']].mean()
print('以均值替换缺失值:\n{0}'.format(df.fillna(fill_value)))

 

整体代码:

import numpy as np
import pandas as pd
from pandas import Series, DataFrame

df1=DataFrame({'key':['a','d','c','a','b','d','c'],'var1':range(7)})
df2=DataFrame({'key':['a','b','c','c'],'var2':[0,1,2,2]})
df=pd.merge(df1, df2, on='key',  how='outer')
df_df = pd.merge(df1, df2, on='key',  how='inner')
df.iloc[0,2]=np.NaN
df.iloc[5,1]=np.NaN
print('合并后的数据:\n{0}'.format(df))

df=df.drop_duplicates()
print('删除重复数据行后的数据:\n{0}'.format(df))
print('判断是否为缺失值:\n{0}'.format(df.isnull()))
print('判断是否不为缺失值:\n{0}'.format(df.notnull()))
print('删除缺失值后的数据:\n{0}'.format(df.dropna()))

fill_value=df[['var1','var2']].mean()
print('以均值替换缺失值:\n{0}'.format(df.fillna(fill_value)))

代码说明:

(1)第4,5行:基于Python字典建立数据框。

(2)第6行:利用Pandas函数merge()将两个数据框依指定关键字做横向合并,生成一个新数据框。

(3)第7,8行:人为指定某样本观测的某变量值为NaN。

(4)第10行:利用Pandas函数drop_duplicates()剔除数据框中在全部变量上均重复取值的样本观测。

(5)第12,13行:利用数据框的.isnull().notnull()方法,对数据框中的每个元素判断其是否为NaN或不是NaN,结果为True或False。

(6)第14行:利用数据框.dropna()方法剔除取NaN的样本观测。

(7)第15行:利用数据框.mean()方法计算各个变量的均值,并存储在名为fill_value的序列中。

(8)第16行:利用数据框的.fillna()方法,将所有NaN替换为指定值(这里为fill_value)。

 

三、 Numpy和Pandas综合应用: 空气质量监测数据的预处理和基本分析

2014年北京市空气质量监测数据

 

 

1、空气质量监测数据的预处理

预处理目标:

根据空气质量检测数据的日期,生成对应的季度标志变量。

对空气质量指数AQI分组,获得对应的空气质量等级。

import numpy as np
import pandas as pd
from pandas import Series,DataFrame

data=pd.read_excel('北京市空气质量数据.xlsx')
data=data.replace(0,np.NaN)
data['']=data['日期'].apply(lambda x:x.year)
month=data['日期'].apply(lambda x:x.month)

quarter_month={'1':'一季度','2':'一季度','3':'一季度',
               '4':'二季度','5':'二季度','6':'二季度',
               '7':'三季度','8':'三季度','9':'三季度',
              '10':'四季度','11':'四季度','12':'四季度'}
data['季度']=month.map(lambda x:quarter_month[str(x)])


bins=[0,50,100,150,200,300,1000]
data['等级']=pd.cut(data['AQI'],bins,labels=['一级优','二级良','三级轻度污染','四级中度污染','五级重度污染','六级严重污染'])
print('对AQI的分组结果:\n{0}'.format(data[['日期','AQI','等级','季度']]))

整体代码:

import numpy as np
import pandas as pd
from pandas import Series,DataFrame

data=pd.read_excel('北京市空气质量数据.xlsx')
data=data.replace(0,np.NaN)
data['']=data['日期'].apply(lambda x:x.year)
month=data['日期'].apply(lambda x:x.month)

quarter_month={'1':'一季度','2':'一季度','3':'一季度',
               '4':'二季度','5':'二季度','6':'二季度',
               '7':'三季度','8':'三季度','9':'三季度',
              '10':'四季度','11':'四季度','12':'四季度'}
data['季度']=month.map(lambda x:quarter_month[str(x)])


bins=[0,50,100,150,200,300,1000]
data['等级']=pd.cut(data['AQI'],bins,labels=['一级优','二级良','三级轻度污染','四级中度污染','五级重度污染','六级严重污染'])
print('对AQI的分组结果:\n{0}'.format(data[['日期','AQI','等级','季度']]))

代码说明:

(1)第5行:利用数据框函数replace()将数据框中的0(表示无监测结果)替换为缺失值NaN。

(2)第6,7行:利用.apply()方法以及匿名函数,基于“日期”变量得到每个样本观测的年份和月份。

(3)第8行:建立一个关于月份和季度的字典quarter_month

(4)第9行:利用Python函数map(),依据字典quarter_month,将序列month中的1,2,3等月份映射(对应)到相应的季度上。

(5)第10行:生成一个后续用于对AQI分组的列表bins。它描述了AQI和空气质量等级的数值对应关系。

(6)第11行:利用Pandas的cut()方法对AQI进行分组。

 2、空气质量监测数据的基本分析

目标:

计算各季度AQI和PM2.5的平均值等描述统计量。

找到空气质量较差的若干天的数据,以及各季度中质量较差的若干天的数据。

计算季度和空气质量等级的交叉列联表。

派生空气质量等级的虚拟变量。

数据集的抽样。

 

2.1 空气质量监测数据的基本分析-基本描述统计

print('各季度AQI和PM2.5的均值:\n{0}'.format(data.loc[:,['AQI','PM2.5']].groupby(data['季度']).mean()))

print('各季度AQI和PM2.5的描述统计量:\n',data.groupby(data['季度'])['AQI','PM2.5'].apply(lambda x:x.describe()))

def top(df,n=10,column='AQI'):
    return df.sort_values(by=column,ascending=False)[:n]

print('空气质量最差的5天:\n',top(data,n=5)[['日期','AQI','PM2.5','等级’]])

print('各季度空气质量最差的3天:\n',data.groupby(data['季度']).apply(lambda x:top(x,n=3)[['日期','AQI','PM2.5','等级']]))

 

print('各季度空气质量情况:\n',pd.crosstab(data['等级'],data['季度'],margins=True,margins_name='总计',normalize=False))

 

整体代码:

print('各季度AQI和PM2.5的均值:\n{0}'.format(data.loc[:,['AQI','PM2.5']].groupby(data['季度']).mean()))
print('各季度AQI和PM2.5的描述统计量:\n',data.groupby(data['季度'])['AQI','PM2.5'].apply(lambda x:x.describe()))
def top(df,n=10,column='AQI'):
    return df.sort_values(by=column,ascending=False)[:n]

print('空气质量最差的5天:\n',top(data,n=5)[['日期','AQI','PM2.5','等级’]])

print('各季度空气质量最差的3天:\n',data.groupby(data['季度']).apply(lambda x:top(x,n=3)[['日期','AQI','PM2.5','等级']]))
print('各季度空气质量情况:\n',pd.crosstab(data['等级'],data['季度'],margins=True,margins_name='总计',normalize=False))

代码说明:

(1)第1行:利用数据框的groupby()方法,计算各季度AQI和PM2.5的平均值。

(2)第2行:计算几个季度AQI和PM2.5的基本描述统计量(均值,标准差,最小值,四分位数,最大值)。

(3)第4,5行:定义了一个名为top的用户自定义函数:对给定数据框,按指定列(默认AQI列)值的降序排序,返回排在前n(默认10)条数据。

(4)第6行:调用用户自定义函数top,对data数据框中,按AQI值的降序排序并返回前5条数据,即AQI最高的5天的数据。

(5)第7行:首先对数据按季度分组,依次对分组数据调用用户自定义函数top,得到各季度AQI最高的3天数据。

(6)第8行:利用Pandas函数crosstab()对数据按季度和空气质量等级交叉分组,并给出各个组的样本量。

 2.2 空气质量监测数据的基本分析-派生虚拟变量

独热编码 one-hot
pd.get_dummies(data['等级'])
data.join(pd.get_dummies(data['等级']))

代码说明:

(1)第1行:利用Pandas的get_dummies得到分类型变量“等级”的哑变量。

(2)第2行:利用数据框的join()方法,将原始数据和哑变量数据,按行索引进行横向合并。

 2.3 空气质量监测数据的基本分析-数据集抽样

抽样或采样,在数据建模中非常普遍。以下两种抽样方法:1)简单随机抽样;2)依条件抽样。

#简单随机抽样
np.random.seed(123)
sampler=np.random.randint(0, len(data), 10) #可以重复
print(sampler)

sampler=np.random.permutation(len(data))[:10]
print(sampler)
data.take(sampler)

 

 

 

#依条件抽样
data.loc[data['质量等级']=='',:]

整体代码:

#简单随机抽样
np.random.seed(123)
sampler=np.random.randint(0, len(data), 10) #可以重复
print(sampler)
sampler=np.random.permutation(len(data))[:10]
print(sampler)
data.take(sampler)
#依条件抽样
data.loc[data['质量等级']=='',:]

代码说明:

(1)第2行:利用Pandas函数random.randint()在指定范围内随机抽取指定个数(这里是10)的随机数。

(2)第 4行:利用Pandas函数random.permutation是对数据随机打乱重排。之后再抽取前10个样本观测。

(3)第7行:利用数据框的take()方法,基于指定随机数获得数据集的一个子集。

(4)第8行:利用数据框访问的方式,抽取满足指定条件(质量等级等于优)行的数据。

 2.4 空气质量监测数据的图形化展示

Matplotlib是Python中最常用的绘图模块,主要特点:

Matplotlib的子模块Pylot与Matlab非常相似,可以方便地绘制各种常见统计图形,是探索数据的重要图形工具。

可通过各种函数设置图形的标题、线条样式、字符形状、颜色等。

 

利用Matplotlib的线图展示2014年至2019年每日AQI的时序变化特点。

 

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

%matplotlib inline
plt.rcParams['font.sans-serif']=['SimHei']  #解决中文显示乱码问题
plt.rcParams['axes.unicode_minus']=False

data=pd.read_excel('北京市空气质量数据.xlsx')
data=data.replace(0,np.NaN)

plt.figure(figsize=(10,5))

 

plt.plot(data['AQI'],color='black',linestyle='-',linewidth=0.5)

plt.axhline(y=data['AQI'].mean(),color='red', linestyle='-',linewidth=0.5,label='AQI总平均值’)

data['']=data['日期'].apply(lambda x:x.year)

AQI_mean=data['AQI'].groupby(data['']).mean().values

year=['2014年','2015年','2016年','2017年','2018年','2019年’]

col=['red','blue','green','yellow','purple','brown']
for i in range(6):
    plt.axhline(y=AQI_mean[i],color=col[i], linestyle='--',linewidth=0.5,label=year[i])

plt.title('2014年至2019年AQI时间序列折线图’)

plt.xlabel('年份’)

plt.ylabel('AQI’)

plt.xlim(xmax=len(data), xmin=1)

plt.ylim(ymax=data['AQI'].max(),ymin=1)
plt.yticks([data['AQI'].mean()],['AQI平均值’])

plt.xticks([1,365,365*2,365*3,365*4,365*5],['2014','2015','2016','2017','2018','2019’])

plt.legend(loc='best’)

#List的index() 函数用于从列表中找出某个值第一个匹配项的索引位置。

x1=list(data['AQI']).index(data['AQI'].max())
y1=data['AQI'].max()-20
plt.text(x=x1,y=y1,s='空气质量最差日',color='red')

plt.show()

 

代码说明:

(1)第3行:Matplotlib的Pyplot子模块,指定别名为plt。

(2)第5至7行:指定立即显示所绘图形,且通过参数设置解决图形中文显示乱码问题。

(3)第12行:利用函数plt.figure说明图形的一般特征,如这里宽为10高5。

(4)第13行:利用函数plt.plot绘制序列折线图(还可以绘制其他图)。同时,指定折线颜色、线形、线宽等。

(5)第14行:利用函数plt.axhline在参数y指定的位置上画一条平行于横坐标的直线,并给定直线图例文字。plt.axvline可参数x指定的位置上画一条平行于纵坐标的直线。

(6)第16至20行:首先,分组计算各年AQI的平均值;然后,通过for循环绘制多条平行于横坐标的直线,表征各年AQI平均值。

(7)第21至23行:利用title()、xlabel()、ylabel()指定图的标题,横纵坐标的坐标标签。

(8)第24,25行:利用xlim()、ylim()指定横纵坐标的取值范围。

(9)第26,27行:利用xticks()、yticks()在指定坐标刻度位置上给出刻度标签。

(10)第28行:利用legend()在指定位置(这里best表示最优位置)显示图例。

(11)第29行:利用text()在指定的行列位置上显示指定文字

(12)第30行:利用show()表示本次绘图结束。

 

 AQI的分布特征及相关性分析

 

 

图形化展示:

利用线图展示2014年至2019年的年均AQI的变化特点。

利用直方图展示2014年至2019年AQI的整体分布特征。

利用散点图展示AQI和PM2.5.5的相关性。

利用饼图展示空气质量等级的分布特征。

 

import warnings #warnings是内置的,不需要安装它。
warnings.filterwarnings(action = 'ignore’)

plt.figure(figsize=(10,5))

plt.subplot(2,2,1)
plt.subplots_adjust(wspace=0.3,hspace=0.5)

#AQI_mean=data['AQI'].groupby(data['年']).mean().values
plt.plot(AQI_mean,color='black',linestyle='-',linewidth=0.5)

plt.title('各年AQI均值折线图’)

plt.xticks([0,1,2,3,4,5],['2014','2015','2016','2017','2018','2019'])
plt.subplot(2,2,2)
plt.hist(data['AQI'], bins=20)

plt.title('AQI直方图’)

plt.subplot(2,2,3)
plt.scatter(data['PM2.5'],data['AQI'],s=0.5,c='green',marker='.’)

plt.title('PM2.5与AQI散点图’)

plt.xlabel('PM2.5’)

plt.ylabel('AQI')
plt.subplot(2,2,4)

tmp=pd.value_counts(data['质量等级'],sort=False)  
#等同:tmp=data['质量等级'].value_counts()

share=tmp/sum(tmp)
labels=tmp.index

explode = [1, 2, 0, 0, 0.5,0,0]

plt.pie(share, explode = explode,labels = labels, autopct = '%3.1f%%',startangle = 180, shadow = True)

plt.title('空气质量整体情况的饼图’)
plt.show()

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2022-09-20 12:40  Gaowaly  阅读(357)  评论(0编辑  收藏  举报
``