目录:
一、numpy
二、pandas
三、matplot
四、seaborn
一、Numpy
1、numpy的介绍
numpy是python语言的一个第三方库,其支持大量高维度数组和矩阵运算(二位数组),此外numpy也针对数组运算提供了大量的数学函数。机器学习涉及到大量对数组的变换和运算,numpy就成了必不可少的工具之一。
numpy是使用python进行科学计算的基础库,主要提供高性能的N维数组计算能力。
2、导入numpy库,并命名为np
import numpy as np
3、如何创建
通过列表创建一维数组:
np.array([1,2,3])
通过列表创建一个二维数组:
np.array([(1,2,3),(4,5,6)])
创建全为0的二维数组:
np.zeros((3,4))
创建全为1的三位数组:
np.ones((2,3,4))
4、数组运算
a = np.array([10, 20, 30, 40, 50])
b = np.arange(1, 6)
a, b
求和
a = np.array([[1, 2], [3, 4]])
np.sum(a)
12.一维数组加法运算:a + b
13 一维数组减法运算:a - b
14. 一维数组乘法运算:a * b
15.一维数组除法运算:a / b
二、Pandas
2.1 pandas
pandas纳入了大量库和一些标准的数据类型,提供了高效地操作大型数据集所需的工具。pandas提供了大量能使我们快捷处理数据的函数和方法。
与numpy对比:numpy能够帮助我们处理数值,pamdas除了处理数值之外,还能帮助我们处理其它类型数据。
pandas主要用于数据分析和数据可视化
2.2pandas常用的数据类型
series: Series类似一维数组,由索引和一组数据组成,其中索引在左边,值在右边。
1、pandas系列可以使用以下构造函数创建
---pandas.series(data,index,dtype)
---data:数据采取各种形式,如:ndarray,list,contants
---index:必须是唯一的和散列的,与数据的长度相同。默认np.arrange(n)如果没有索引被传递
---dtype用于数据类型。如果没有,将推断数据类型。
import pandas as pd
import numpy as np
data=np.array(["a","b","c","d"])
s=pd.series(data) #index默认np.arrange(n)如果没有索引被传递
print(s)
s=pd.series(data,index=[100,1011,102,103])
print(s)
输出结果:
0 a
1 b
2 c
3 d
type: object
100 a
101 b
102 c
103 d
dtype: object
2.从字典(dict)数据创建pandas系列,字典作为输入传递,如果没有指定索引,则按照排列顺序取得字典键构造索引,如果传递了索引,索引中与标签对应的数据中的值将被拉出
import pandas as pd
import numpy as np
data={"a":0.,"b":1.,"c":2.}
s=pd.series(data) #没有指定索引,则按照排列顺序取得字典键构造索引
print(s)
s=pd.series(data,["b","c","d","a"]) #传递了索引,索引中与标签对应的数据中的值将被拉出
print(s)
输出结果:
a 0.0
b 1.0
c 2.0
dtype: float64
b 1.0
c 2.0
d NaN
a 0.0
dtype: float64
3.从标量数据创建Pandas系列,数据是标量值,则必须提供索引。将重复
该值以匹配索引的长度
import pandas as pd
import numpy as np
s = pd.Series(5, index=[0, 1, 3])
print(s)
输出结果:
0 5
1 5
3 5
dtype: int64
DataFrame:数组帧(DataFrame)是二维数据结构,即数据以行和列的表格方式排列
pandas中的DataFrame可以使用以下构造函数构建:pandas.DataFrame(data,index,columns,dtype)
• data数据采取各种形式,如:ndarray,series,map,lists,dict,constant和另一个DataFrame。
• index对于行标签,要用于结果帧的索引是可选缺省值np.arrange(n),如果没有传递索引值。
• columns对于列标签,可选的默认语法是 - np.arange(n)。 这只有在没有索引传递的情况下才是这样。
• dtype每列的数据类型。
import pandas as pd
import numpy as np
df = pd.DataFrame()#empty DataFrame
print(df)
data = [1, 2, 3, 4, 5]
df = pd.DataFrame(data) #from list
print(df)
data = [['Alex', 10], ['Bob', 12], ['Clarke', 13]]
df = pd.DataFrame(data, columns=['Name', 'Age']) # from list
print(df)
输出结果:
Empty DataFrame Columns: []
Index: []
0
0 1
1 2
2 3
3 4
4 5
Name Age
0 Alex 10
1 Bob 12
2 Clarke 13
三、matplotlib
matplotlib基本介绍
matplotlib是一个在python下实现的类matplot的纯python的第三方库,旨在python实现matlab的功能,是python下最出色的绘图库。
matplotlib中应用最广的是matlpotlib.pyplot模块
matplotlib绘图基础
.figure() :创建一个新的绘图窗口。
.figtext() :为figure添加文字
.axes() :为当前figure添加一个坐标轴
.plot() :绘图函数
.axis() :坐标的取值范围
.test() :在轴上添加文字
.xlabel/ylabel() :设置当前图框状态;off或者on
.imread() :读取一个图像,从图像文件中提取数组
.legend() :为当前axes放置标签
.scatter() :做一个x和y的散点图,其中x和y是相同长度的序列对象
1.创建画布与创建子图
plt.figure()创建一个空白画布,指定画布大小,像素。
figure.add_subplot() :创建并选中子图,可以指定子图的行数,列数,与选中图片编号
plt.figure()主要作用是构建出一张空白的画布,figure.add_subplot() 选择将整个画布划分为多个部分,方便在同一画布上绘制多个图形的情况。最简单的绘图plt.figure(),而后直接在默认的画布上进行图形绘制。
import matplotlib.pyplot as plt
import numpy as np
data=np.arrange(10)
plt.plot(data) #plt.plot()绘图函数
输出结果:
绘制的图位于图片(figure)对象中。
创建子图
import matplotlib.pyplot as plt
fig=plt.figure() #本次绘图有多个子图,不能使用空白的figure绘图,需要创建子图
ax1=fig.add_subplot(2,2,1)
ax2=fig.add_subplot(2,2,2)
ax3=fig.add_subplot(2,2,3)
输出结果:
import matplotlib.pyplot as plt
fig=plt.figure() #本次绘图有多个子图,不能使用空白的figure绘图,需要创建子图
fig=plt.figure() #本次绘图有多个子图,不能使用空白的figure绘图,需要创建子图
ax1=fig.add_subplot(2,2,1)
ax2=fig.add_subplot(2,2,2)
ax3=fig.add_subplot(2,2,3)
ax1.plot([1.5,2,3.5,-1,1.6])
输出结果:
2.添加画布内容
函数名称 函数作用
plt.title 在当前图形中添加标题,可以指定标题的名称、位置、颜色、字体大小等参数。
plt.xlabel 在当前图形中添加x轴名称,可以指定位置、颜色、字体大小等参数。
plt.ylabel 在当前图形中添加y轴名称,可以指定位置、颜色、字体大小等参数。
plt.xlim 定当前图形x轴的范围,只能确定一个数值区间,而无法使用字符串标识。
plt.ylim 指定当前图形y轴的范围,只能确定一个数值区间,而无法使用字符串标识。
plt.xticks 指定x轴刻度的数目与取值。
plt.yticks 指定y轴刻度的数目与取值。
plt.legend 指定当前图形的图例,可以指定图例的大小、位置、标签。
这一部分是绘图的主体部分。其中添加标题,坐标轴名称,绘制图形等步骤是并列的,没有先后顺序,可以先绘制图形,也可以先添加各类标签。但是添加图例一定要在绘制图形之后。
import numpy as np
import matplotlib.pyplot as plt
data=np.arrange(0,1,0.01)
plt.title("my lines example")
plt.xlabel("x")
plt.ylabel("y")
plt.xlim(0,1)
plt.ylim(0,1)
plt.xticks([0,0.2,0.4,0.6,0.8,1])
plt.yticks([0,0.2,0.4,0.6,0.8,1])
plt.plot(data,data**2)
plt.plot(data,data**3)
plt.legend(['y=x^2','y=x^3'])
plt.show()
输出结果:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
data=np.arange(0,np.pi*2,0.01)
fig1=plt.figure(figsize=(9,7),dpi=90)
#确定画布大小
#绘制第一幅子图
ax1=fig1.add_subplot(1,2,1)
plt.title('lines example')
plt.xlabel('X')
plt.ylabel('Y')
plt.xlim(0,1)
plt.ylim(0,1)
plt.xticks([0,0.2,0.4,0.6,0.8,1])
plt.yticks([0,0.2,0.4,0.6,0.8,1])
plt.plot(data,data**2)
plt.plot(data,data**3)
#绘制第二幅子图
ax1=fig1.add_subplot(1,2,2)
plt.title('sin-cos')
plt.xlabel('X')
plt.ylabel('Y')
plt.xlim(0,np.pi*2)
plt.ylim(-1,1)
plt.xticks([0,np.pi/2,np.pi,np.pi*3/2,np.pi*2])
plt.yticks([-1,-0.5,0,0.5,1])
plt.plot(data,np.sin(data))
plt.plot(data,np.cos(data))
plt.legend(['sin','cos'])
plt.show()
输出结果:
Matplotlib 的 Legend 图例就是为了帮助我们展示每个数据对应的图像名称,更好的让读者认识到你的数据结构。关于plt.legend()的说明如下:
常用设置示例:
plt.legend(loc = 'best',frameon = False)
#去掉图例边框,推荐使用
plt.legend(loc = 'best',edgecolor = 'blue')
#设置图例边框颜色
plt.legend(loc = 'best',facecolor = 'blue')
#设置图例背景颜色,若无边框,参数无效
3.绘图的保存与显示
函数名称 | 函数作用 |
---|---|
plt.savafig | 保存绘制的图片,可以指定图片的分辨率、边缘的颜色等参数。 |
plt.show | 在本机显示图形 |
第三部分主要用于保存和显示图形。
fig.savefig(save_path, format='png', transparent=True, dpi=300, pad_inches = 0)
figure.savefig选项
四、seaborn
>seaborn简介
seaborn是基于matplotlib的数据可视化库。它在matplotlib的基础上,进行了更高级的封装,从而使得绘图更加容易,不需要经过大量的调整,就能使图像变得精致。
seaborn的几个鲜明特点如下:
>绘图接口更加集成,可以通过少量的参数设置实现大量封装绘图。
>多数图表具有统计学含义,例如分布、关系、统计、回归等
>对pandas和numpy数据类型支持非常友好
>导入seaborn
seaborn的依赖库为numpy、pandas、matplotlib、scipy。
>import numpy as np
>import pandas as pd
>import seaborn as sns
>import matplotlib.puplot as plt
>from scipy import stats,integrate
1、深度了解Seaborn
1.1 鸢尾花识别
假设我们要创建一个智能手机应用程序,从智能手机拍摄的照片中自动识别花的种类。 我们正在与一个数据科学家团队合作,该数据科学主管负责创建一个演示机器学习模型,测量花的萼片长度 (sepal length),萼片宽度 (sepal width),花瓣长度 (petal length) 和花瓣宽度 (petal width) 四个变量,并根据这些测量识别物种。
那么什么是萼片呢?萼片是花的最外一环。下图清晰指出花的萼片和花瓣。
我们的数据集里面包括三种类型的鸢尾花的测量,如下图
根据每种鸢尾花的四个数据 (萼片长/宽和花瓣长/宽),我们最终目的是想正确的分类这三种花。但重中之重的第一步是数据处理,有了干净数据之后再来机器学习很容易。
但怎么处理数据有时候更像一门艺术而不像一门科学。接下来会从
1.检查数据
2.清理数据
3.测试数据
三方面来探索,在其过程中当然会借助 Seaborn.
即便是政府或银行,他们公布的数据也有错误。在花费太多时间分析数据之前,提早检查并修正这些错误能节省大量时间。一般来说,我们希望回答以下问题:
1.据格式有什么问题吗?
2.数据数值有什么问题吗?
3.数据需要修复或删除吗?
检查点1.数据格式
首先用 pandas 读取 csv 文件并将数据存成 DataFrame 格式。
iris_data = pd.read_csv( 'iris-data.csv', na_values=['NA'] )
函数 read_csv() 里面用到的两个参数
此行代码将 csv 里的数据转成 pandas 里的数据表,命名为 iris_data。接着查看其前 10 个数据。
iris_data.head(10)
数据看起来是可用的 (大神 Hadley Wickhan 对干净数据的定义是,每一列代表一个特征;每一行代表一个样例)。
数据的第一行定义了列标题,标题的描述足以让我们了解每个列代表的内容 (萼片长度,萼片宽度,花瓣长度和花瓣宽度),标题甚至给我们记录测量的单位 (cm, 厘米)
第一行之后的每一行代表一个花的观测数据:四个测量指标和一个类 (class),它告诉我们花的种类。比如前 10 个都是山鸢尾花 (注意第 8 到 10 个的花瓣宽度没有数据,用 NaN 来表示)。
检查点2.数据统计
接下来,检查数据的分布可以识别异常值。我们从数据集的汇总统计数据开始。
iris_data.describe()
解释一下上表:
describe() 函数的产出每列数据的个数 (count),均值 (mean),标准差 (std),最小值 (min) 25, 50 和 75 百分位数 (25%, 50%, 75%) 和最大值 (max)。50 百分位数也就是中位数 (median)。
从该表中看到几个有用的值。 例如,我们看到缺少 5 条花瓣宽度的数据 (表里 count 那一行的萼片长度,萼片宽度和花瓣长度的个数都是 150 个,唯独花瓣宽度是 145 个)。
此外,这样的表给不了太多有用信息,除非我们知道数据应该在一个特定的范围 (如萼片长度的最小值是 0.055, 和它其他指标如均值和几个百分位数都不是量纲的,很有可能是测量错误)。
你说表中这些数字看起来是不是很枯燥,为什么不用直观的图呢?现在 seaborn 可以派上用场了。
sb.pairplot(iris_data.dropna(), hue='class')
上面 pairplot() 函数里
> 第一个参数 iris_data.dropna() 就是除去 NaN 的数据表,这么做原因很简单,图里不可能显示的出 NaN 值的。
> 第二个参数 hue = ‘class’ 就是根据类 (class) 下不同的值赋予不同的颜色 (hue 是色彩的意思)
让我们再回顾一下 iris_data 的前 10 行:
它有 5 列,前四列 (萼片长度,萼片宽度,花瓣长度和花瓣宽度) 可看成自变量,第五列 (类) 可看成变量。
配对图 (pairplot) 绘制前四列变量的关系图,而且用不同颜色区分不同的类下面的这四个变量。 从上图可知,横轴纵轴都有四个变量,那么总共可以画出 16 (4*4) 张小图。
>对角线上的 4 张都是某个变量和自身的关系,用分布图 (dist plot)。
>非对角线的 12 张就是某个变量和另一个变量的关系,用散点图 (scatter plot)。比如第一行第二列的图描述的就是萼片长度 (看纵轴第一个 sepal_length_cm 字样) 和萼片宽度 (看横轴第二个 sepal_width_cm 字样)。
让再回顾「配对图」
从「配对图」中,我们可以迅速看出数据集上的一些问题:
1.图的右侧标注这五个类 (Iris-setosa, Iris-setossa, Iris-versicolor, versicolor, Iris-virginica),但原本要分类的花只有三类 (Iris-setosa, Iris-versicolor, Iris-virginica)。这意味着在记录数据时可能会犯下一些错误。
2.在测量中有一些明显的异常值可能是错误的。
第二行的图 1-2-4 (或第二列的图1-2-4),对于 Iris-setosa,一个萼片宽度 (sepal_width) 值落在其正常范围之外。
第一行后三张图 (或第一列后三张图),对于 Iris-versicolor,几个萼片长度 (sepal_length) 值都接近零。
下一步我们的任务是要处理错误的数据。
修正点1.数据类型
问题:按理说鸢尾花应该只有三类,而图中显示有五类。
通过观察数据的标签,我们发现
现在让我们使来修正这些错误。
>iris_data.loc[iris_data['class']=='versicolor','class']='Iris-versicolor'
>iris_data.loc[iris_data['class']=='Iris-setossa','class']='Iris-setosa'
>iris_data['class'].unique()
第一行将 versicolor 改为 Iris-versicolor;第二行将 Iris-setossa 改为 Iris-setosa;第四行用 unique() 函数 (unique 有唯一不重复的意思) 检验修改过的数据只有三类,更新后再画「配对图」。
sns.pairplot(iris_data.dropna(), hue='class')
完美!五个类减到三个类,而且名称正确,分别是 Iris-setosa, Iris-versicolor 和 Iris-virginica。
修正点2.异常值
修正异常值 (outliers) 是一件棘手的事情。因为我们很难判断异常值是否由测量误差引起,或者是不正确的单位记录数据,或者是真正的异常。如果我们决定排除任何数据,需要记录排除的数据并提供排除该数据的充分理由。由上节所知,我们有两种类型的异常值。
问题1:山鸢尾花的一个萼片宽度值落在其正常范围之外。
通过调查我们知道,山鸢尾花 (Iris-setosa) 的萼片宽度 (sepal_width_cm) 不可能低于 2.5 厘米。显然,这个记录是错误的,这种情况下最有效的方法是删除它而不是花时间查找原因。但是,我们仍需要知道有多少个类似这样的错误数据,如果很少删除它没有问题,如果很多我们需要查明原因
cond = (iris_data['class'] == 'Iris-setosa')
& (iris_data['sepal_width_cm'] < 2.5)
iris_data.loc[cond]
上面代码是用数据表里的 loc[] 切片来找到类为 Iris-setoa 并且 sepal width 小于 2.5 的所有行。最后发现只有一个这样的数据,因此可以直接删除此数据。
去掉 Iris-setosa 里萼片宽度大于 2.5 厘米的数据,然后画出其条形图。
iris_data = iris_data.loc[~cond]
iris_data.loc[iris_data['class'] == 'Iris-setosa',
'sepal_width_cm'].hist()
从上面条形图也看到了再没有这个异常值 (小于 2.5 厘米的点)。
完美! 现在所有的山鸢尾花的萼片宽度都大于 2.5 厘米
问题2:变色鸢尾花的几个萼片长度值接近于零。
所有这些接近零的 sepal_length_cm 似乎错位了两个数量级,好像它们的记录单位米而不是厘米。在经过了解,我们发现错误是因为忘记将这些测量值转换为厘米。
我们使用代码来修正这些错误。
cond = (iris_data['class'] == 'Iris-versicolor')
& (iris_data['sepal_length_cm'] < 1.0)
iris_data.loc[cond]
>iris_data.loc[cond, 'sepal_length_cm'] *= 100.0
>iris_data.loc[iris_data['class'] == 'Iris-versicolor','sepal_length_cm'].hist()
从上面条形图也看到了再没有这五个异常值 (零点零几的点)。
完美! 我们成功修正了这些异常值,要不然以后会 GIGO (Garbage In Garbage Out)
修正点3.缺失值
对了,我们还有些 NaN 这样的缺失值 (missing value)。通常我们有两种方式来处理这类数据。
删除 (deletion)
插补 (imputation)
在本例中删除不是理想的做法,特别是考虑到它们都在 Iris-setosa 下,如图:
所有缺失的值都属于 Iris-setosa类,直接删除可能会对日后数据分析带来偏差。此外,可以用插补方法,其最常见的方法平均插补 (mean imputation)。其做法就是“假设知道测量的值落在一定范围内,就可以用该测量的平均值填充空值”。
首先查看缺失值在 DataFrame 哪个位置
iris_data.loc[(iris_data['sepal_length_cm'].isnull())|
(iris_data['sepal_width_cm'].isnull())|
(iris_data['petal_length_cm'].isnull())|
(iris_data['petal_width_cm'].isnull())]
上面代码里面 iris_data[A].isnull() 语句是找出 A 列中值为 NA 或 NaN 的行,而 “|” 是“或”的意思。因此上面整句话是找到萼片长度,萼片宽度,花瓣长度和花瓣宽度这四列下的所有含 NaN 的行数据,最后发现只有 5 行,而且 NaN 都来自花瓣宽度。
然后用 mean() 求出其宽度的平均值,用其将 NaN 值全部代替,最后打印出那 5 行插补后的 DataFrame。
>isSetosa=iris_data['class']=='Iris-setosa'
>average_petal_width=iris_data.loc[isSetosa,'petal_width_cm'].mean()
>iris_data.loc[isSetosa & >(iris_data['petal_width_cm'].isnull()),'petal_width_cm']=average_petal_width
>iris_data.loc[isSetosa & (iris_data['petal_width_cm']==average_petal_width)]
为了确保所有 NaN 值已被替换,再次用 iris_data[A].isnull() 语句来查看,出来的结果是一个只有列标题的空数据表。这表示表内已经没有 NaN 值了。
> iris_data.loc[(iris_data['sepal_length_cm'].isnull())|
(iris_data['sepal_width_cm'].isnull())|
(iris_data['petal_length_cm'].isnull())|
(iris_data['petal_width_cm'].isnull())]
经过了修正类别、异常值和缺失值后,最后来看看基于干净数据画的「配对图」吧。
sns.pairplot( iris_data, hue='class' )
从上图可看到:
五个类变成三个类
异常值全部被删除
缺失值全部被插补
图整洁了,数据也干净了,之后可以用来做机器学习。
3.加载样本数据
seaborn附带了样本数据集,所有数据集均为csv格式,数据集默认存放在线上,地址为https://github.com/mwaskom/seaborn-data
。
3.1获取样本数据地址seaborn.get_data_home()
函数签名为seaborn.get_data_home(data_home=None)
。
返回值为样本数据集的缓存地址。这个用于seaborn.load_dataset()
。
3.2加载数据集seaborn.load_dataset()
3.2.1 默认从网络加载数据集。
函数的签名为seaborn.load_dataset(name,cache=True,data_home=None,**kws)。
函数的参数为:
> name
:数据集的名称,对应https://github.com/mwaskom/seaborn-data
中name.csv
。字符串。
> cache
:是否从网络下载数据集。布尔值。可选参数。当取值为True
时,首选从本地缓存加载数据,如果下载数据会将数据缓存在本地。
> data_home
:缓存目录。字符串,可选参数。默认值为None
,即get_data_home()
。
> kws
:传递给pandas.read_csv()
的附加参数。键值对,可选参数。
返回值为pandas.DataFrame
。
3.2.2加载本地数据集
由于数据集默认从github下载,由于网络不稳定或者没有网络,所以直接访问数据集可能不方便,因此加载本地数据集比较灵活。
加载本地数据集的步骤如下:
1、直接从https://github.com/mwaskom/seaborn-data 下载数据集。
2、将数据集保存在同一个目录中,比如D:\seaborn-data。
3、加载数据时,设置load_dataset函数的cache参数为True,data_home参数为D:\seaborn-data。即sns.load_dataset('iris',data_home=r'D:\seaborn-data',cache=True)
3.2.3加载自定义数据集
除了seaborn
附带的数据集,也可以自己创建数据。
根据load_data()
函数概述可知,其原理就是利用pandas.read_csv()
函数读取csv
文件,因此,只要数据最终被转换为DataFrame
格式即可。