科学计算常用模块
- Numpy:Arrays manipulation library 科学计算的必装模块,几乎所有的其他科学模块都依赖于它
- Scipy:扩展的科学计算模块
- PyGSL:C/C++语言中著名的科学计算函数库GNU Scientific Library(GSL)的python版
- Matplotlib:高质量的2D作图模块,足以替代GNUPlot
- Mayavi:强大的三维作图模块,属于EPD公司套件的一部分(注意:此模块支持Python2,官方未支持Python3)
- Sympy:符号计算模块
- StatLib:统计学工具箱
- Escript/Finley:偏微分方程求解
- Parallel Python:并行计算模块
下面我们来详细介绍其中的numpy和scipy模块。
Numpy是Python的扩展模块,提供了矩阵、线性代数、傅里叶变换等的解决方法。 NumPy包含:N维矩阵对象、线性代数运算功能、傅里叶变换、Fortran代码集成的工具、C++代码集成的工具。
SciPy是基于Numpy构建的一个集成了多种数学算法和方便的函数的Python模块。 SciPy的子模块需要单独import。 Scipy包含:constants物理和数学常数、fftpack快速傅立叶变换程序、integrate 积分和常微分方程求解器、interpolate拟合和平滑曲线、 linalg线性代数、optimize最优路径选择、signal信号处理、sparse稀疏矩阵和以及相关程序、special特殊函数、stats统计上的函数和分布等。
Python中用列表(list)保存一组值,可以用来当作数组使用,不过由于列表的元素可以是任何对象,因此列表中所保存的是对象的指针。这样为了保存一个简单的[1,2,3],需要有3个指针和三个整数对象。对于数值运算来说这种结构显然比较浪费内存和CPU计算时间。 此外Python还提供了一个array模块,可以直接保存数值,但是不支持多维,也没有各种运算函数,因此也不适合做数值运算。 NumPy的诞生弥补了这些不足,NumPy提供了两种基本的对象:ndarray(N-dimensional array object)和ufunc(universal function object)。 ndarray(下文统一称之为数组)是存储单一数据类型的多维数组,而ufunc则是能够对数组进行处理的函数。
>>> import numpy as np
>>> a = np.array([1, 2, 3, 4], dtype='int32')
>>> a = np.array([[3,4,5],[3,6,7]])
np.arange(0,1,0.1) np.zeros(2,3) np.ones(5)
np.linspace(0, 1, 12) np.logspace(0, 2, 20)
函数式创建:
def func(i, j):
return (i+1) * (j+1)
a = np.fromfunction(func, (9,9))
>>> a=range(5)
>>> a + 1
>>> a * 2
>>> a + a
>>> a > 3
>>> np.array(a)
>>> b=np.arange(5)
>>> b + 1
>>> b * 2
>>> b + b
>>> b > 3
>>> b / 2
>>> list(b)
>>> a = np.arange(10)
>>> a[5] # 用整数作为下标可以获取数组中的某个元素
>>> a[3:5] # 用范围作为下标获取数组的一个切片,包括a[3]不包括a[5]
>>> a[:5] # 省略开始下标,表示从a[0]开始
>>> a[:-1] # 下标可以使用负数,表示从数组后往前数,array([0, 1, 2, 3, 4, 5, 6, 7, 8])
>>> a[2:4] = 100,101 # 下标还可以用来修改元素的值
>>> a[1:-1:2] # 范围中的第三个参数表示步长, 2表示隔一个元素取一个元素
>>> a = np.arange(10).reshape(2,-1)
>>> a
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
>>> a[1,1] #单个元素
6
>>> a[1] #整行
array([5, 6, 7, 8, 9])
>>> a[:,2] #整列
array([2, 7])
>>> a[0][::2] #抽取某行特定元素
array([0, 2, 4])
>>> a = np.arange(10).reshape(-1,2)
>>> a[a[:,1]>3]
array([[4, 5],
[6, 7],
[8, 9]])
>>> a[a[:,1]%3==0]
array([[2, 3],
[8, 9]])
>>> a[(a[:,1]>3)*(a[:,1]%3==0)]
argsort函数返回数组值从小到大的索引
>>> x = np.array([3,1,2])
>>> np.argsort(x)
>>> x[np.argsort(x)] # 排序后的数组
>>> x=np.array([[0,3],[4,2]])
>>> np.argsort(x, axis=1) # 排序每行
>>> a[a[:,1].argsort()] # 按第二列排序
>>> a = np.arange(6).reshape(2,3)
>>> a.shape
(2, 3)
>>> a.dtype
dtype('int32')
分别试试a.sum() a.min() a.max() a.mean()
>> a.reshape(3,2) #转置a.T
>> a.ravel() #展开数组
>> a.repeat(2,axis=0) #复制元素
>>> a = np.array([1, 2, 3])
>>> b = np.array([2, 3, 4])
>>> np.r_[a,b]
>>> np.hstack((a,b))
array([1, 2, 3, 2, 3, 4])
>>> np.vstack((a,b))
array([[1, 2, 3],
[2, 3, 4]])
>>> np.c_[a,b]
array([[1, 2],
[2, 3],
[3, 4]])
很多时候我们需要将程序运算得到的数据进行存储,Numpy为我们提供了存储数据的函数。格式如下:
numpy.savetxt(fname, X, fmt='%.18e',delimiter=' ', newline='\n', header='',footer='', comments='# ')
>>> x = y = z = np.arange(0.0,5.0,0.5)
>>> np.savetxt('test.out', x, delimiter=',')
# X is an array
>>> np.savetxt('test.out', (x,y,z))
# x,y,z equal sized 1D arrays
>>> np.savetxt('test.out', x, fmt='%6.4f')you
# use exponential notation
既然更够存储数据,那一定也有读取之前已经存储的数据的方法。函数的格式如下:
numpy.loadtxt(fname, dtype=<type 'float'>,comments='#', delimiter=None,converters=None, skiprows=0, usecols=None,unpack=False, ndmin=0)
让我们来读取刚才已经存储的数据
>>> data = np.loadtxt('test.out', dtype = float)
>>> data = np.loadtxt('test.out', usecols=[1])
Python本身其实自带math库以用于一般的数学计算,Numpy中的函数是针对数组设计的,且更为快速和强大,这里我们来弄清楚二者的具体区别。
import time, math
import numpy as np
n = 1e+6
x = range(int(n))
start = time.clock()
for i in x:
tmp = math.sin(i/n)
print("math.sin:", time.clock() - start)
x = np.array(x)/n
start = time.clock()
np.sin(x)
print("numpy.sin:", time.clock() - start)