Python是一种面向对象的,动态的程序设计语言,具备很是简洁而清晰的语法,适合于完成各类高层任务。它既能够用来快速开发程序脚本,也能够用来开发大规模的软件。html
随着NumPy、SciPy、Matplotlib、Enthoughtlibrarys等众多程序库的开发,Python愈来愈适合于作科学计算、绘制高质量的2D和3D图像。与科学计算领域最流行的商业软件MATLAB相比,Python是一门通用的程序设计语言,比MATLAB所采用的脚本语言的应用范围更普遍,有更多的程序库的支持。虽然MATLAB中的许多高级功能和toolbox目前仍是没法替代的,不过在平常的科研开发之中仍然不少的工做是能够用Python代劳的。python
经常使用的模块概览与导入程序员
1.数值计算库算法
NumPy为Python提供了快速的多维数据处理的能力,而SciPy则在NumPy基础上添加了众多的科学计算所需的各类工具包,有利这两个库,Python就具备几乎与MATLAB同样的处理数据和计算的能力了。编程
NumPy和SciPy官方网址分别为http://www.numpy.org/和https://www.scipy.org/数组
NumPy为Python带来了真正的多维数据处理功能,而且提供了丰富的函数库处理这些数组。它将经常使用的数学函数进行数组化,使得这些数学函数可以直接对数组进行操做,将原本须要在Python级别进行的循环,放到C语言的运算中,明显地提升了程序的运算速度。编程语言
SciPy的核心计算部分都是一些久经考验的Fortran数值计算库,例如:函数
2.符号计算库工具
SymPy是一套进行符号数学运算的Python函数库,它足够好用,能够帮助咱们进行公式推导,进行符号求解。动画
SymPy官方网址:http://www.sympy.org/en/index.html
3.界面设计
制做界面一直都是一件十分复杂的工做,使用Traits库,将使得咱们没必要再界面设计上耗费大量精力,从而能把注意力集中到如何处理数据上去。
Traits官方网站:http://code.enthought.com/pages/traits.html
Traits库分为Traits和TraitsUI两大部分,Traits为Python添加了类型定义的功能,使用它定义的Traits属性具备初始化、校验、代理、事件等诸多功能。
TraitsUI库基于Traits库,使用MVC结构快速地定义用户界面,在最简单的状况下,编码者都不须要写一句关于界面的代码,就能够经过Traits属性定义得到一个能够工做的用户界面。使用TraitsUI库编写的程序自动支持wxPython和pyQt两个经典的界面库。
4.绘图与可视化
Chaco和Matplotlib是很优秀的2D绘图库,Chaco库和Traits库紧密相连,方便制做动态交互式的图表功能。而Matplotlib库则可以快速地绘制精美的图表,以各类格式输出,而且带有简单的3D绘图的功能。
Chaco官方网站:http://code.enthought.com/projects/chaco/
Matplotlib官方网站:https://matplotlib.org/
TVTK库在标准的VTK库之上用Traits库进行封装,若是要在Python下使用VTK,用TVTK是再好不过的选择。Mayavi2则在TVTK的基础上再添加了一套面向应用的方便工具,它既能够单独做为3D可视化程序使用,也能够快速地嵌入到用户的程序中去。
Mayavi官方网址:http://code.enthought.com/pages/mayavi-project.html
视觉化工具函式库(Visualization Toolkit,VTK)是一个开放源码,跨平台、支援平行处理(VTK曾用与处理大小近乎1个Petabyte的资料,其平台为美国Los Alamos国家实验室全部的具备1024个处理器之大型系统)的图形应用函式库。2005年曾被美国陆军研究实验室用于即时模拟俄罗斯制反导弹战车ZSU23-4受到平面波攻击的情形,其计算节点高达2.5兆之多。
此外,使用Visual库可以快速、方便地制做3D动画演示,使数据结果更有说服力。
Visual官方网站:http://vpython.org/
5.图像处理和计算机视觉
openCV由英特尔公司发起并参与开发,以BSD许可证受权发行,能够在商业和研究领域中无偿使用。OpenCV可用于开发实时的图像处理、计算机视觉及模式识别程序。OpenCV提供的Python API方便咱们快速实现算法,查看结果而且和其余的库进行数据交换。
Numpy简介
标准安装的Python中用列表(list)保存一组值,能够用来当作数组使用,可是因为列表的元素能够是任何对象,所以列表中所保存的是对象的指针。这样为了保存一个简单的[1,2,3],须要有3个指针和3个整数对象。对于数值运算来讲这种结构显然比较浪费内存和CPU计算时间。
此外,Python还提供了一个array模块,array对象和列表不一样,它直接保存数值,与C语言的一维数组比较相似。可是因为它不支持多维,也没有各类运算函数,所以不适合作数值运算。
NumPy的诞生弥补了以上不足,NumPy提供了两种基本的对象:ndarray(N-dimensional array object)和ufunc(universal function object)。ndarray(后面内容统一称之为数组)是存储单一数据类型的多维数组,而ufunc则是可以对数组进行处理的函数。
1)Numpy库的导入
在进行Numpy相关操做时,在此须要先导入该库:
import numpy as np #导入numpy以后使用np可代替numpy
2)数组的建立与生产
首先须要建立数组才能对其进行其余操做。能够经过给array函数传递Python的序列对象来建立对象,若是传递的是多层嵌套的序列,将建立多维数组
1.直接复制建立数组:
#数组建立直接赋值 import numpy as np a=np.array([1,2,3,4]); b=np.array([5,6,7,8]); c=np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]]); print(a.shape);#a的shape属性 print(a); print(b); print(c);#多维数组 print(c.shape);#c的shape属性 print(c.dtype)#查看c的数据类型 #output: # (4,) # [1 2 3 4] # [5 6 7 8] # [[ 1 2 3 4] # [ 5 6 7 8] # [ 9 10 11 12]] # (3, 4) # int32
2.改变数组的形式:经过shape属性查看并更改。数组a的shape只有一个元素,所以它是一维数组。而数组c的shape有两个元素,所以它是二维数组,其中第0轴的长度为3,第1轴的长度为4.还能够经过修改数组的shape属性,还保持数组元素个数不变的状况下,改变数组每一个轴的长度。
下面的例子将数组c的shape改成(4,3),注意从(3,4)改成(4,3)并非对数组进行转置,而只是改变每一个轴的大小,数组元素在内存中的位置并无改变:
#接上面程序 c.shape=3,4; print(c.shape); print(c) c.shape=4,3; print(c.shape); print(c) # output: # (3, 4) # [[ 1 2 3 4] # [ 5 6 7 8] # [ 9 10 11 12]] # (4, 3) # [[ 1 2 3] # [ 4 5 6] # [ 7 8 9] # [10 11 12]]
3.使用reshape方法,从新改变数组的尺寸,而原数组的尺寸不变:
#接上面程序 print(a) d=a.reshape(2,2) print(d) print(a) # output: # [1 2 3 4] # [[1 2] # [3 4]] # [1 2 3 4]
4.数组a和d实际上是共享数据存储内存区域的,所以修改其中任意一个数组的元素都会同时修改另一个数组的内容:
#接上面程序 print(d) a[0]=1000000;#将数组a的一个元素改成1000000 print(d) # output: # [[1 2] # [3 4]] # [[1000000 2] # [ 3 4]]
5.前面所说的都是默认的dtype,如今改变其dtype参数:
# 指定数据类型 e=np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]],dtype=np.float); print(e) # output: # [[ 1. 2. 3. 4.] # [ 5. 6. 7. 8.] # [ 9. 10. 11. 12.]]
6.固然,到如今为止,所建立的array都是基于手动赋值操做,Python还提供一些函数能够自动化地建立数组。
# 利用函数建立数组 # numpy中的arange()函数相似于Python中的range()函数 # 经过指定开始值,终值和步长来建立一维数组,注意数组不包括终值 arr1=np.arange(0,10,1.0); print(arr1); # output: # [0. 1. 2. 3. 4. 5. 6. 7. 8. 9.] #linspace函数经过指定开始值,终值和元素的个数来建立一维数组 #能够经过endpoint关键字指定是否包括终值,缺省设置是包括终值 print(np.linspace(0,1,12)); # output: # [0. 0.09090909 0.18181818 0.27272727 0.36363636 0.45454545 # 0.54545455 0.63636364 0.72727273 0.81818182 0.90909091 1. ] # logspace函数和linspace函数相似,不过它建立等比数列 #下面的例子产生1(10^0)到10(10^2),有10个元素的等比数列 print(np.logspace(0,2,10)) # output: # [ 1. 1.66810054 2.7825594 4.64158883 7.74263683 # 12.91549665 21.5443469 35.93813664 59.94842503 100. ]
3)利用数组进行数据处理
1.多维数组
在具体的应用中咱们更多的是使用多维数组进行数据处理,而多维数组的存取和一维数组相似,只是多维数组有多个轴,所以,它的下标须要多个值来表示。Numpy采用元组(tuple)做为数组的下标。
2.多维数组建立
0 | 1 | 2 | 3 | 4 | 5 |
10 | 11 | 12 | 13 | 14 | 15 |
20 | 21 | 22 | 23 | 24 | 25 |
30 | 31 | 32 | 33 | 34 | 35 |
40 | 41 | 42 | 43 | 44 | 45 |
50 | 51 | 52 | 53 | 54 | 55 |
《=======数组a
首先来看如何建立该数组,数组a其实是一个加法表,纵轴的值为0,10,20,30,40,50;横轴的值为0,1,2,3,4,5。纵轴的每一个元素与横轴的每一个元素求和获得上表中所示的数组a。
arr2=np.arange(0,6)+np.arange(0,60,10).reshape(-1,1); print(arr2); # output: # [[ 0 1 2 3 4 5] # [10 11 12 13 14 15] # [20 21 22 23 24 25] # [30 31 32 33 34 35] # [40 41 42 43 44 45] # [50 51 52 53 54 55]]
3.多维数组存取
多维数组一样也可使用整数序列和布尔数组进行存取。
import numpy as np arr2=np.arange(0,6)+np.arange(0,60,10).reshape(-1,1); print(arr2) # output: # [[ 0 1 2 3 4 5] # [10 11 12 13 14 15] # [20 21 22 23 24 25] # [30 31 32 33 34 35] # [40 41 42 43 44 45] # [50 51 52 53 54 55]] # 第一种获取 a=arr2[(0,1,2,3,4),(1,2,3,4,5)];#至关于arr2[0][1],arr2[1][2].... print(a); # output: # [ 1 12 23 34 45] # 第二种获取 # 注意:别忘了中间的逗号 a=arr2[3:,[0,2,5]];#至关因而从第3行到最后一行的第0列,第2列,第5列 print(a) # output: # [[30 32 35] # [40 42 45] # [50 52 55]] # 第三种获取(经过bool值获取数组的数据) mask=np.array([1,0,1,0,0,1],dtype=np.bool) print(mask)#mask制做的是bool型列表 print(arr2[mask,2])#至关于行都是布尔值(true表示显示,false表示不显示),列都是2 # 注意:在此处mask充当的是行,那么它的值的数量必须和行数相等,不然则报错 # output: # [ True False True False False True] # [ 2 22 52]
用于数组的文件输入输出
1)把数组数据写入file
保存数组数据的文件能够是二进制格式或者是文本格式。但不会保存数组数组形状和元素类型等信息。
a=np.arange(0,16).reshape(4,4); a.tofile(r'C:\Users\123\Desktop\a.bin')#文件后缀是bin a.tofile(r'C:\Users\123\Desktop\a.txt')#文件后缀是txt
保存的后文件内容彷佛不能有价值的人工读取。
2)读取文件file中的数组
由于保存时就未保存数组形状和元素类型等信息,故读取时必须为你要使用的数组设置合适的形状和元素类型。
#! /usr/bin/env python #coding=utf-8 import numpy as np a=np.arange(0,16).reshape(4,4); print(a) a.tofile(r'C:\Users\123\Desktop\a.bin')#文件后缀是bin a.tofile(r'C:\Users\123\Desktop\a.txt')#文件后缀是txt b=np.fromfile(r'C:\Users\123\Desktop\a.txt',dtype=np.int32); print(); print("取出后的信息并未保存存入文件时的数组类型和元素类型信息:"); print(b); b.shape=4,4; print(); print("从txt文件中提取:"); print(b); c=np.fromfile(r'C:\Users\123\Desktop\a.bin'); print(); print("从bin文件中提取:"); print(c); # output: # [[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11] # [12 13 14 15]] # 取出后的信息并未保存存入文件时的数组类型和元素类型信息: # [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15] # 从txt文件中提取: # [[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11] # [12 13 14 15]] # 从bin文件中提取: # [2.12199579e-314 6.36598737e-314 1.06099790e-313 1.48539705e-313 # 1.90979621e-313 2.33419537e-313 2.75859453e-313 3.18299369e-313]
3)numpy.load和numpy.save
numpy.load和numpy.save函数以Numpy专用的二进制类型保存数据,这两个函数会自动处理元素类型和shape等信息,使用它们读写数组就方便多了,可是numpy.save输出的文件很难用其余语言编写的程序读入(由于数据读取问题,利用numpy.save进行保存到的文件,在使用其余编程语言进行读取时增长了难度)。
np.save(r'C:\Users\123\Desktop\a.npy',a);#后缀名称为.npy d=np.load(r'C:\Users\123\Desktop\a.npy'); print(d); # output: # [[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11] # [12 13 14 15]]
4)numpy.savetxt和numpy.loadtxt
使用numpy.savetxt和numpy.loadtxt能够读写一维和二维的数组。
a=np.arange(0,12,0.5).reshape(4,-1); print(a); np.savetxt(r'C:\Users\123\Desktop\aTxt.txt',a);#缺省值按照“%.18e”格式保存数据,以空格分隔 print("读取信息:") print(np.loadtxt(r'C:\Users\123\Desktop\aTxt.txt')); # output: # [[ 0. 0.5 1. 1.5 2. 2.5] # [ 3. 3.5 4. 4.5 5. 5.5] # [ 6. 6.5 7. 7.5 8. 8.5] # [ 9. 9.5 10. 10.5 11. 11.5]] # 读取信息: # [[ 0. 0.5 1. 1.5 2. 2.5] # [ 3. 3.5 4. 4.5 5. 5.5] # [ 6. 6.5 7. 7.5 8. 8.5] # [ 9. 9.5 10. 10.5 11. 11.5]]
使用该方法获得的文件能够人工读取。
也可将数组该保存在整数。
np.savetxt(r'C:\Users\123\Desktop\aTxt.txt',a,fmt="%d",delimiter=",");#改保存为整数,以逗号分隔 #读入的时候也须要自定逗号分隔(能够看到这样的方式数据失真) print(np.loadtxt(r'C:\Users\123\Desktop\aTxt.txt',delimiter=",")) # output: # [[ 0. 0. 1. 1. 2. 2.] # [ 3. 3. 4. 4. 5. 5.] # [ 6. 6. 7. 7. 8. 8.] # [ 9. 9. 10. 10. 11. 11.]]
此时,文件是这样的。
数组的算术和统计运算
1)数组的算术
数组的算术在实际的应用过程当中大都经过矩阵matrix的运算来实现,Numpy和MATLAB不同,对于多维数组的运算,缺省值的状况下并不使用矩阵运算,若是但愿对数组的进行矩阵运算的话,能够调用相应的函数。之因此在Python中加入matrix运算是由于它的运算快,并且数组通常的表示就是一维、二维数组,值得注意的是虽然基于矩阵matrix运算代码较少,执行效率高,可是比较考验程序员的数学水平,而基于数组的运算能够多谢一堆代码,可是若是数据量大的状况下执行的运算容易崩溃,此处简单介绍matrix运算。
#能够把matrix理解为多维数组 ma=np.matrix([[1,2,3],[4,5,6],[7,8,9]]); print(ma); # output: # [[1 2 3] # [4 5 6] # [7 8 9]]
2)基于矩阵matrix的运算
#能够把matrix理解为多维数组 ma=np.matrix([[1,2,3],[4,5,6],[7,8,9]]); ma+ma #矩阵加法 # output: # matrix([[ 2, 4, 6], # [ 8, 10, 12], # [14, 16, 18]]) ma-ma #矩阵减法 # output: # matrix([[0, 0, 0], # [0, 0, 0], # [0, 0, 0]]) ma*ma #矩阵乘法 # ouput: # matrix([[ 30, 36, 42], # [ 66, 81, 96], # [102, 126, 150]]) ma**-1 #矩阵求逆 # output: # matrix([[ 3.15251974e+15, -6.30503948e+15, 3.15251974e+15], # [-6.30503948e+15, 1.26100790e+16, -6.30503948e+15], # [ 3.15251974e+15, -6.30503948e+15, 3.15251974e+15]])
3)基于矩阵matrix的统计运算
1.dot内积(能够基于一维数组,也能够基于两个矩阵)运算
a=np.arange(12).reshape(3,4); b=np.arange(12,24).reshape(4,3); c=np.dot(a,b);#求a和b的内积 print(a); print(); print(b); print(); print(c); # output: # [[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11]] # [[12 13 14] # [15 16 17] # [18 19 20] # [21 22 23]] # [[114 120 126] # [378 400 422] # [642 680 718]]
2.inner运算
与dot乘积同样,对于两个一维数组,计算的是这两个数组对应下标元素的乘积和;对于多维数组,它计算的结果数组中的每一个元素都是数组a和b的最后一维的内积,所以数组a和b的最后一维的长度必须相同。
a=np.arange(12).reshape(3,4); b=np.arange(12,24).reshape(3,4);#注意此处和dot运算要求不同 c=np.inner(a,b);#求a和b的内积 print(a); print(); print(b); print(); print(c); # output: # [[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11]] # [[12 13 14 15] # [16 17 18 19] # [20 21 22 23]] # [[ 86 110 134] # [302 390 478] # [518 670 822]]
3.outer运算
只按照一维数组进行运算,若是传入参数是多维数组,则先将此数组展平为一维数组以后再进行运算。outer乘积计算的是列向量和行向量的矩阵乘积:
a=np.arange(12).reshape(3,4); b=np.arange(12,24).reshape(3,4);#注意此处和inner运算要求同样 c=np.outer(a,b); print(c); # output: # [[ 0 0 0 0 0 0 0 0 0 0 0 0] # [ 12 13 14 15 16 17 18 19 20 21 22 23] # [ 24 26 28 30 32 34 36 38 40 42 44 46] # [ 36 39 42 45 48 51 54 57 60 63 66 69] # [ 48 52 56 60 64 68 72 76 80 84 88 92] # [ 60 65 70 75 80 85 90 95 100 105 110 115] # [ 72 78 84 90 96 102 108 114 120 126 132 138] # [ 84 91 98 105 112 119 126 133 140 147 154 161] # [ 96 104 112 120 128 136 144 152 160 168 176 184] # [108 117 126 135 144 153 162 171 180 189 198 207] # [120 130 140 150 160 170 180 190 200 210 220 230] # [132 143 154 165 176 187 198 209 220 231 242 253]]
5.数组统计运算
针对数组进行统计计算,如下只是经过简单的例子来讲明能够基于数组进行相应的统计计算,更多的统计函数参考Python手册(numpy部分)。
#统计数组 a=np.arange(12).reshape(3,4); print("a矩阵:\n",a); #以第0行数据为例进行统计运算 print("第0行:\n",a[0]); print("和值:\n",np.sum(a[0])); print("平均值:\n",np.mean(a[0])); print("方差:\n",np.var(a[0])); # output: # a矩阵: # [[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11]] # 第0行: # [0 1 2 3] # 和值: # 6 # 平均值: # 1.5 # 方差: # 1.25
参考书目:《数据馆员的Python简明手册》