1.Python数据分析入门
数据分析:就是把隐藏在一些看似杂乱无章的数据背后的信息提炼出来,总结出所研究对象的内在规律。
Python数据分析常用库:Numpy,Pandas,Matplotlib,scripy和Scikit-Learn。
2.Numpy库
NumPy 通常与 SciPy(Scientific Python)和 Matplotlib(绘图库)一起使用, 这种组合广泛用于替代 MatLab,是一个强大的科学计算环境,有助于我们通过 Python 学习数据科学或者机器学习。
2.1.Numpy的应用
SciPy 是一个开源的 Python 算法库和数学工具包。
SciPy 包含的模块有最优化、线性代数、积分、插值、特殊函数、快速傅里叶变换、信号处理和图像处理、常微分方程求解和其他科学与工程中常用的计算。
Matplotlib 是 Python 编程语言及其数值数学扩展包 NumPy 的可视化操作界面。它为利用通用的图形用户界面工具包,如 Tkinter, wxPython, Qt 或 GTK+ 向应用程序嵌入式绘图提供了应用程序接口(API)。
2.2.Numpy库中常混用的方法
NumPy的主要对象是同构多维数组.他是一个元素表(通常是数字),都是相同的类型,有正整数元组索引,在NumPy维度中成为轴.
例如,3D空间中的点的坐标[1,2,1]具有一个轴,该轴有三个元素,所以说它的长度为3,在下面所示的例子中,数组有两个轴,第一个轴长度为2,第二个轴的长度为3(通俗的说就是两行三列).
[[ 1., 0., 0.], [ 0., 1., 2.]]
NumPy的数组类被调用ndarray。它也被别名所知 array。请注意,numpy.array这与标准Python库类不同array.array,后者只处理一维数组并提供较少的功能。ndarray对象更重要的属性是:
ndarray.ndim --- 数组的轴数(尺寸)
ndarray.shape --- 数组的大小,这是一个整数元组,表示每个维度中数组的大小,对于具有n行和m列的矩阵,shape将是(n,m).shape因此元组的长度是轴的数量ndim
ndarray.size --- 数组的元素总数。这等于元素的乘积shape
ndarray.itemsize --- 数组中每个元素的大小(以字节为单位)。例如,类型的元素数组float64有itemsize8(= 64/8),而其中一个类型complex32有itemsize4(= 32/8)。它相当于ndarray.dtype.itemsize。
ndarray.data --- 包含数组实际元素的缓冲区。通常,我们不需要使用此属性,因为我们将使用索引工具访问数组中的元素。
#Numpy、数组array概念初识 import numpy as np a = np.arange(15).reshape(3,5)#创建二维数组 print(a.shape) # 查看每个维度中数组的大小 #结果:(3,5) print(a.ndim) # 数组的轴数,二维数组 #结果:2 print(a.dtype.name) # 描述数组中元素类型的对象 #结果:int32 print(a.itemsize) # 数组中每个元素的大小为4字节 #结果:4 print(a.size) # 数组的元素总数 #结果:15 print(type(a)) #结果:<class 'numpy.ndarray'> #创建一个数组 import numpy as np from numpy import array b = np.array([6, 7, 8]) b1 = array([6, 7, 8]) # 创建一个数组 print(type(b)) #<class 'numpy.ndarray'> print(type(b1)) #<class 'numpy.ndarray'> np.array([[1,2,3],['a','b',1.1]]) # 创建一个二维数组 array([['1', '2', '3'],['a', 'b', '1.1']], dtype='<U11')
2.3.数组的创建
创建数组有以下几种方法:
使用array函数从常规python列表或元组创建数组,结果数组的类型是从序列中元素的类型推导出来的
import numpy as np a = np.array([2,3,4]) print(a.dtype) #结果:int32 b = np.array([1.2, 3.5, 5.1]) print(b.dtype) #结果:float64
注意:
- numpy默认ndarray的所有元素的类型是相同的
- 如果传进来的列表中包含不同的类型,则统一为统一类型,优先级 str > float > int
也可以在创建时显式指定数组类型:
b = np.array([(1.5,2,3), (4,5,6)]) print(b) #结果: [[1.5 2. 3. ] [4. 5. 6. ]] c = np.array([[1,2],[3,4]],dtype=complex) print(c) #结果: [[1.+0.j 2.+0.j] [3.+0.j 4.+0.j]]
通常,数组的元素最初是未知的,但其大小是已知的。因此,NumPy提供了几个函数来创建具有初始占位符内容的数组。
函数zeros创建一个充满零的数组,
函数ones创建一个完整的数组,
函数empty创建一个数组,其初始内容是随机的,取决于内存的状态.默认情况下,创建的数组的dtype是float64。
a = np.zeros((3,3)) b = np.ones((2,3,4),dtype=np.int16) c = np.empty((3,3)) print(a) #结果: [[0. 0. 0.] [0. 0. 0.] [0. 0. 0.]] print(b) #结果: [[[1 1 1 1] [1 1 1 1] [1 1 1 1]] [[1 1 1 1] [1 1 1 1] [1 1 1 1]]] print(c) #结果: [[9.486e-322 0.000e+000 0.000e+000] [0.000e+000 0.000e+000 1.146e-321] [0.000e+000 0.000e+000 0.000e+000]]
为了创建数字序列,NumPy提供了一个类似于range返回数组而不是列表的函数
arange和Python里的range非常相似;arange产生的也是一个连续序列。序列的类型不再是列表,是数组array。两数组可以直接相加,在numpy内部完成循环。
a = np.arange( 10, 30, 5 )
b =np.arange( 0, 2.2) # it accepts float arguments
print(a)
print(b)
# 第一个参数开始数字,第二个是结束数字,第三个类似步长
当arange与浮点参数一起使用时,由于有限的浮点精度,通常不可能预测所获得的元素的数量。出于这个原因,通常最好使用linspace作为参数接收我们想要的元素数量的函数,而不是步骤:
e = np.linspace( 0,2,9) print(e) # # from numpy import pi f =np.linspace(0,2*pi,100) print(f) *****************两组不一样的结果****************** e = np.arange( 0,2,9) print(e) # # from numpy import pi f =np.arange(0,2*pi,100) print(f)
2.4数组打印
当您打印数组时,NumPy以与嵌套列表类似的方式显示它,但具有以下布局:
- 最后一个轴从左到右打印,
- 倒数第二个是从上到下打印的,
- 其余部分也从上到下打印,每个切片用空行分隔。
然后将一维数组打印为行,将二维数据打印为矩阵,将三维数据打印为矩阵列表。
a = np.arange(6) # 然后将一维数组打印为行 print(a) b = np.arange(12).reshape(4,3) # 将二维数据打印为矩阵 print(b) c = np.arange(24).reshape(2,3,4) # 将三维数据打印为矩阵列表 print(c)
如果数组太大而无法打印,NumPy会自动跳过数组的中心部分并仅打印角落:
print(np.arange(10000)) [ 0 1 2 ..., 9997 9998 9999] print(np.arange(10000).reshape(100,100)) [[ 0 1 2 ..., 97 98 99] [ 100 101 102 ..., 197 198 199] [ 200 201 202 ..., 297 298 299] ..., [9700 9701 9702 ..., 9797 9798 9799] [9800 9801 9802 ..., 9897 9898 9899] [9900 9901 9902 ..., 9997 9998 9999]]
要禁用此行为并强制NumPy打印整个阵列,可以使用更改打印选项set_printoptions。
np.set_printoptions(threshold=np.nan)
2.5.数组的基本操作
数组上的算术运算符应用于元素。创建一个新数组并填充结果。
a = np.array([[1,2],[3,4]]) b = np.array([[5,6],[7,8]]) s1 = a+b s2 = a-b s3 = a**2 print(s1) print(s2) print(s3) print(a<3) print(a@b)
某些操作(例如+=和)*=用于修改现有阵列而不是创建新阵列。
a = np.ones((2,3), dtype=int) b = np.random.random((2,3)) print(a) print(b) a *= 3 b += a a += b #TypeError: Cannot cast ufunc add output from dtype('float64') to dtype('int64') with casting rule 'same_kind' 这是因为优先级问题str > float > int
当使用不同类型的数组进行操作时,结果数组的类型对应于更一般或更精确的数组(称为向上转换的行为)
from numpy import pi
a = np.ones(3, dtype=np.int32)
b = np.linspace(0,pi,3)
print(a.dtype.name)
print(b.dtype.name)
c = a+b
print(c)
print(c.dtype.name)
d = np.exp(c*1j)
print(d)
print(d.dtype.name)
许多一元操作,例如计算数组中所有元素的总和,都是作为ndarray类的方法实现的。
a = np.random.random((2,3)) a.sum() a.min() a.max()
默认情况下,这些操作适用于数组,就像它是一个数字列表一样,无论其形状如何。但是,通过指定axis 参数,您可以沿数组的指定轴应用操作:
b = np.arange(12).reshape(3,4) b.sum(axis=0) # 列的总和 b.min(axis=1) # 行的总和 array([0, 4, 8]) b.cumsum(axis=1) # cumulative sum along each row
3.数据可视化
3.1.matplotlib库(数学绘图库:math数学、plot绘图、lib库)
matplotlib.pyplot(缩写)
定制化绘图:.mp.plot(xxx,linestyle=线型,linewidth=线宽,color=颜色)
看手册功能:help(mo.plot)
设置图标范围
mp.xlim(左边界,右边界)
mp.ylim(底边界,顶边界)
显示弧度值:
mp.xticks(刻度位置数组,刻度文本数组)
mp.yticks(刻度位置数组,刻度文本数组)
刻度转义方法:[r'$-pi$',r'$-frac{pi}{2}$',r'$0$',r'$frac{pi}{2}$',r'$frac{3pi}{4}$',r'$pi$']
引十字坐标:
作用:拿到框线的轴
ax = mp.gca() #获取当前坐标轴
ax.spines['left'].set_position(('data',0)) #设置位置边框(有四边)
ax.spines['left'].set_color(颜色) #设置位置边框颜色。
显示图例和位置
mp.plot(...,lable=r'$y=sin(x)$')
mp.legend(loc='uper left')
标记一些特殊点
散点图(不连线)
mp.scatter(水平坐标数组,垂直坐标数组,marker=点型,s=大小,edgecolor=勾边色,facecolor=填充色,zorder=Z序)
Z序就是绘画的顺序,zorder数越大,点越晚压在线上。matplotlib绘画顺序是先画点 再画线。
图上做注释:
mp.annotate(备注文本,xy=目标位置,xycoords=目标坐标系,xytext=文本位置,textcoorder=文本坐标系,fontsize=文字大小,arrowprops=箭头属性)
4.图形对象
具体写法:
mp.figure(图形对象名,figsize=窗口大小,dpi=分辨率,facecolor=窗口颜色)
mp.figure()方法:第一次调用是创建,第二次调用为再次置为当前窗口。
mp.title()写标题:mp.title('xxx',fontsize=20)
mp.xlable()坐标轴的标签:mp.xlabel(标签文字,字体大小)--->mp.xlabel('xx',fontsize=12)
mp.tick_params()设置刻度参数:mp.tick_params(labelsize=10)
mp.grid()设置格线:mp.grid(linestyle=‘:’)
子图:
创建子图,大图里创建子图
1)缺省(默认)布局:
mp.subplot(行数,列数,图号)
eg:mp.subplot(2,3,1)或mp.subplot(231)
子图显示文字:
mp.text(对应中心位置比例,对应中心位置比例,数值,ha=水平对齐方式,va=垂直对其方式,size=尺寸大小,qlpha=透明度)
mp.tight_layout() 紧凑 不空很多格 边距变窄
2)栅格布局
先建立一个格栅布局器:
import matplotlib.gridspec as mp
gs = mg.GridSpec(行数,列数)
mp.subplot(gs[行,列])
优点:布局匀称
3)自由布局
mp.axes([左下角水平坐标,左下角垂直坐标,宽度,高度])
优点:所有尺寸参数都是相对比例
缺点:同时输入几个,最后一张图能在另一张里边。
5.坐标刻度定位器
定位器对象 = mp.xxxLocateor(...)
ax = mp.gca()
主刻度:ax.xaxis.set_major_locator(定位器对象)——>x轴,让定位器对象帮我们定义刻度。
次刻度:ax.xaxis.set_minor_locator(定位器对象)———>x轴,让定位器对象帮我们定义刻度。
locators = [ 'mp.NullLocator()',#空定位器,不需要参数,可以被解释执行 'mp.MaxNLocator(nbins=3, steps=[1, 3, 5, 7, 9])',#最多分三段,从后续列表中选一个等分的点 'mp.FixedLocator(locs=[0, 2.5, 5, 7.5, 10])',#固定定位器。等价于直接调用xticks。 'mp.AutoLocator()',#自动定位器。特点:间隔不太密也不太疏,自顶匹配。 'mp.IndexLocator(offset=0.5, base=1.5)',#索引定位器。offset起始点,base是间隔点 'mp.MultipleLocator()',#次刻度定位器。 'mp.LinearLocator(numticks=21)',#线性均分定位器。numticks=21等分成20分
'mp.LogLocator(base=2, subs=[1.0])' #指数定位器。
]
6.散点图
散点图的意义:
可以让一个点附带更多信息。
总是用两个坐标x,y坐标来表示。
eg:代表身高,y代表年龄
a = np.random.normal(0,1,n)----->这是正态分布规律的随机数,其中0代表平均值μ,1代表标准差,n代表数量。
区域填充
mp.fill_between(水平坐标数组,垂直坐标数组,垂直坐标终点数组,条件,color=颜色,alpha=透明度)
7.柱状图
mp.bar(水平坐标数组,高度数组,ec=边缘颜色,fc=填充颜色,label=标签文本,alpha=透明度)
mp.bar(水平坐标数组,高度数组,宽度,color=颜色,label=标签文本,alpha=透明度)
y1=np.random.uniform(0.5,1.0,n)---->在0.5到1.0内生成n个随机数
8.扇形图
mp.pie(值,间隙,标签,颜色,格式,shadow=是否带阴影,startangle=起始角度)
9.等高线图
用途:用二维的图形来展示三维数据,多用于地理中。
mp.contour(x,y,z,线数,colors=颜色,linewidth=线宽)
mp.contourf(x,y,z,线数,cmap=颜色映射)
meshgrid函数:
10.热像图
mp.imshow(矩阵,cmap=颜色映射,origin=确定y轴方向)
11.三维曲面图
主要指:三维贴面 和 三维线框
引用库:from mpl_toolkits.mplot3d import axes3d
ax=mp.gca(projection='3d')#创建三维效果的坐标轴
ax.plot_surface(x,y,z,rstride=行距,cstride=列距,cmap=颜色映射)
ax.plot_wireframe(x,y,z,rstride=行距,cstride=列距,linewidth=线宽,cmap=颜色映射)
12.三位散点图
from mpl_toolkits.mplot3d import axes3d
ax=mp.gca(projection='3d')#创建三维效果的坐标轴
ax.scatter(x, y, z, s=大小, c=颜色, cmap='jet_r', alpha=0.5,marker=点型)
13.极坐标系
mp.gca(projection='polar')#二维
mp.plot()
mp.scatter()
x,y(x代表极角,y代表极径)
14.简单动画
第一种方式:给定一个函数,自己不调取,让别人调取。
eg:def更新函数(顺序号):
更新画面帧
第二种方式:多加一个生成器,把这个生成器当做一个可迭代对象去迭代,迭代的过程中,不断生成数据,并把生成的数据作为参数去调用。通过第二个函数传入的更新函数,由他完成渲染。
通过一个函数产生数据,另一个函数渲染数据,从数据结构上更合理,符合低耦合的设计原则。
eg:def 更新函数(生成值):
更新画面帧
def 生成器():
for xxx in yyy:
生成新的数据
yield 生成值
anim=ma.FuncAnimation(mp.gcf(),update,interval=10)