1、简介
Python是一种流行的通用编程语言,在科学领域被广泛使用。你很容易在Python代码中调用以前的C、Fortran或者R代码。Python是面向对象语言,比C和Fortran更加高级。使用Python可以写出易读、整洁并且缺陷最少的代码。然而,Python本身并不具有与Matlab等效的功能块,而这恰恰就是NumPy存在的意义。除NumPy以外,相关的Python科学计算库还有,SciPy和Matplotlib。ipython是一个净强化的交互Python Shell,对探索NumPy的特性非常方便;matplotlib将允许你绘图;Scipy在NumPy的基础上提供了很多科学模块;
NumPy(Numerical Python的缩写)是一个开源的Python科学计算库。使用NumPy,就可以很自然地使用数组和矩阵。NumPy包含很多实用的数学函数,涵盖线性代数运算、傅里叶变换和随机数生成等功能。如果你的系统中已经装有LAPACK,NumPy的线性代数模块会调用它,否则NumPy将使用自己实现的库函数。LAPACK是一个著名的数值计算库,最初是用Fortran写成的,Matlab同样也需要调用它。从某种意义上讲,NumPy可以取代Matlab和Mathematica的部分功能并且允许用户进行快速的交互式原型设计
NumPy能够直接对数组和矩阵进行操作,可以省略很多循环语句,其众多的数学函数也会让编写代码的工作轻松许多;了NumPy的两个特性:向量化(Vectorization)和广播(Broadcasting),它们是NumPy强大之处的基础。
向量化用于描述任何缺失的显式循环、索引及其它,在代码这些事情是即时发生;一般来说,NumPy中所有操作,并不只是算术运算,还有逻辑运算,位运算,函数运算等,以这种隐式的元素层面的方式执行,就是广播。
NumPy中数组的存储效率和输入输出性能均远远优于Python中等价的基本数据结构;NumPy数组的通用性不及Python提供的list容器,这是其不足之处;
NumPy的大部分代码都是用C语言写成的,这使得NumPy比纯Python代码高效得多;
列表操作:
c = []
for i in range(len(a)):
c.append(a[i]*b[i])
C语言,一维数组:
for (i = 0; i < rows; i++)
{c[i] = a[i]*b[i];}
C语言,二维数组:
for (i = 0; i < rows; i++)
{
for (j = 0; j < columns; j++)
{
c[i][j] = a[i][j]*b[i][j];
}
}
Numpy,
c = a * b
2、Numpy函数总览
创建数组:
arange, array, copy, empty, empty_like, eye, fromfile, fromfunction, identity, linspace, logspace, mgrid, ogrid, ones,ones_like, r , zeros, zeros_like
转化:
astype, atleast 1d, atleast 2d, atleast 3d, mat
操作:
array split, column stack, concatenate, diagonal, dsplit, dstack, hsplit, hstack, item, newaxis, ravel, repeat, reshape,resize, squeeze, swapaxes, take, transpose, vsplit, vstack
询问:
all, any, nonzero, where
排序:
argmax, argmin, argsort, max, min, ptp, searchsorted, sort
运算:
choose, compress, cumprod, cumsum, inner, fill, imag, prod, put, putmask, real, sum
基本统计:
cov, mean, std, var
基本线性函数:
cross, dot, outer, svd, vdot
3、基础操作
3-1 ndarray:
在NumPy中维度(dimensions)叫做轴(axes),轴的个数叫做秩(rank)。注意numpy.array和标准Python库类array.array并不相同,后者只处理一维数组和提供少量功能。
属性有:ndarray.ndim(秩),ndarray.shape(维度,这是一个指示数组在每个维度上大小的整数元组),ndarray.size(数组元素的总个数,等于shape属性中元组元素的乘积),ndarray.dtype(用来描述数组中元素类型的对象),ndarray.itemsize(数组中每个元素的字节大小),ndarray.data(实际数组元素的缓冲区)
3-2 创建数组:
a = array([2,3,4])
b = array( [ (1.5,2,3), (4,5,6) ] )
zeros( (3,4) )
ones( (2,3,4), dtype=int16 )
empty( (2,3) )
arange( 10, 30, 5 )
当arange使用浮点数参数时,由于有限的浮点数精度,通常无法预测获得的元素个数。因此,最好使用函数linspace去接收我们想要的元素个数来代替用range来指定步长。其它函数array, zeros, zeros_like, ones, ones_like, empty, empty_like, arange, linspace, rand, randn, fromfunction, fromfile。
3-3 打印数组:
a = arange(6)
print(a)
b = arange(12).reshape(4,3)
print(b)
c = arange(24).reshape(2,3,4)
print(c)
3-4 基本运算:
a = array( [20,30,40,50] )
b = arange( 4 )
c = a - b
b ** 2
10 * sin( a )
>>> a < 35
array([True, True, False, False], dtype=bool
矩阵乘法:
A = array( [[1,1],
[0,1]] )
B = array( [[2,0],
[3,4]] )
C = A * B
dot(A, B)
改变矩阵的值:
a = ones((2,3), dtype=int)
b = random.random((2,3))
a *= 3
b += a
a += b
a = ones(3, dtype=int32)
b = linspace(0, pi, 3)
c = a + b
d = exp(c*1j)
d.dtype.name
数组累加:
a = random.random((2,3))
a.sum()
a.min()
a.max()
数组轴操作:
b = arange(12).reshape(3,4)
b.sum(axis=0) # 每列相加
b.min(axis=1) # 每行最小
b.cumsum(axis=1) # 按行累计
3-5 通用函数:
all, alltrue, any, apply along axis, argmax, argmin, argsort, average, bincount, ceil, clip, conj, conjugate, corrcoef,
cov, cross, cumprod, cumsum, diff, dot, floor, inner, inv, lexsort, max, maximum, mean, median, min, minimum, nonzero,
outer, prod, re, round, sometrue, sort, std, sum, trace, transpose, var, vdot, vectorize, where。
3-6 索引,切片和和迭代:
一维数组:
a = arange(10)**3
a[2]
a[2:5]
a[:6:2] = -1000 # from start to position 6, exclusive, set every 2nd element to - 1000
a[ : :-1] # reversed a
二维数组:
def f(x,y):
return 10 * x + y
>>> b = fromfunction(f,(5,4),dtype=int)
array([[ 0, 1, 2, 3],
[10, 11, 12, 13],
[20, 21, 22, 23],
[30, 31, 32, 33],
[40, 41, 42, 43]])
b[2,3]
>>> b[0:5, 1] # each row in the second column of b
array([ 1, 11, 21, 31, 41])
>>> b[ : ,1] # equivalent to the previous example of b
array([ 1, 11, 21, 31, 41])
>>> b[-1] # the last row. Equivalent to b[-1,:]
array([40, 41, 42, 43])
"""
如果x是秩为5的数组(即它有5个轴),那么:
x[1,2,…] 等同于 x[1,2,:,:,:],
x[…,3] 等同于 x[:,:,:,:,3]
x[4,…,5,:] 等同 x[4,:,:,5,:]
"""
c = array( [[[ 0, 1, 2], [ 10, 12, 13]],
[[100,101,102],[110,112,113]] ] )
>>> c.shape
(2, 2, 3)
>>> c[1,...]
array([[100, 101, 102],[110,112,113]])
>>> c[...,2]
array([[ 2, 13], [102, 113]])
迭代多维数组是就第一个轴而言的:[2](0轴)
>>> for row in b:
print row
[0 1 2 3][10 11 12 13][20 21 22 23][30 31 32 33][40 41 42 43]
>>> for element in b.flat:
print element
0 1 2 3 10 11 12 13 20 21 22 23 30 31 32 33 40 41 42 43
3-7 更改数组的形状
>>> a = floor(10*random.random((3,4)))
>>> a
array([[ 7., 5., 9., 3.],[ 7., 2., 7., 8.],[ 6., 8., 3., 2.]])
>>> a.shape
(3, 4)
>>> a.ravel() # flatten the array
array([ 7., 5., 9., 3., 7., 2., 7., 8., 6., 8., 3., 2.])
>>> a.shape = (6, 2)
>>> a.transpose()
array([[ 7., 9., 7., 7., 6., 3.],[ 5., 3., 2., 8., 8., 2.]])
array([[ 7., 5.],[ 9., 3.],[ 7., 2.],[ 7., 8.],[ 6., 8.],[ 3., 2.]])
>>> a.resize((2,6))
>>> aarray([[ 7., 5., 9., 3., 7., 2.],[ 7., 8., 6., 8., 3., 2.]])
3-8 组合不同的数组
垂直和水平
>>> a = floor(10*random.random((2,2)))
>>> a
array([[ 1., 1.],[ 5., 8.]])
>>> b = floor(10*random.random((2,2)))
>>> b
array([[ 3., 3.],[ 6., 0.]])
>>> vstack((a,b))
array([[ 1., 1.],[ 5., 8.],[ 3., 3.],[ 6., 0.]])
>>> hstack((a,b))
array([[ 1., 1., 3., 3.],[ 5., 8., 6., 0.]])
column_stack:函数column_stack以列将一维数组合成二维数组
>>> column_stack((a,b)) # With 2D arrays
array([[ 1., 1., 3., 3.],[ 5., 8., 6., 0.]])
>>> a=array([4.,2.])
>>> b=array([2.,8.])
>>> a[:,newaxis] # This allows to have a 2D columns vector
array([[ 4.],[ 2.]])
>>> column_stack((a[:,newaxis],b[:,newaxis]))
array([[ 4., 2.],[ 2., 8.]])
>>> vstack((a[:,newaxis],b[:,newaxis])) # The behavior of vstack is different
array([[ 4.],[ 2.],[ 2.],[ 8.]
3-9 分割数组
使用hsplit你能将数组沿着它的水平轴分割,或者指定返回相同形状数组的个数,或者指定在哪些列后发生分割:
>>> a = floor(10*random.random((2,12)))
>>> aarray([[ 8., 8., 3., 9., 0., 4., 3., 0., 0., 6., 4., 4.],
[ 0., 3., 2., 9., 6., 0., 4., 5., 7., 5., 1., 4.]])
>>> hsplit(a,3) # Split a into 3
[ array([[ 8., 8., 3., 9.],[ 0., 3., 2., 9.]]),
array([[ 0., 4., 3., 0.],[ 6., 0., 4., 5.]]),
array([[ 0., 6., 4., 4.],[ 7., 5., 1., 4.]])]
>>> hsplit(a,(3,4)) # Split a after the third and the fourth column
[array([[ 8., 8., 3.],[ 0., 3., 2.]]),
array([[ 9.],[ 9.]]),
array([[ 0., 4., 3., 0., 0., 6., 4., 4.],[ 6., 0., 4., 5., 7., 5., 1., 4.]]
3-10复制和视图
不同的数组对象分享同一个数据。视图方法创造一个新的数组对象指向同一数据
>>> c = a.view()
>>> c is a
False
>>> c.base is a # c is a view of the data owned by aTrue
>>> c.flags.owndata
False
>>> c.shape = 2,6 # a's shape doesn't change
>>> a.shape(3, 4)
>>> c[0,4] = 1234 # a's data changes
>>> a
array([[ 0, 1, 2, 3],[1234, 5, 6, 7],[ 8, 9, 10, 11]
切片数组返回它的一个视图
>>> s = a[ : , 1:3] # spaces added for clarity; could also be written "s = a[:,1:3]"
>>> s[:] = 10 # s[:] is a view of s. Note the difference between s=10 and s[:]=10
>>> a
array([[ 0, 10, 10, 3],[1234, 10, 10, 7],[ 8, 10, 10, 11]
深复制
>>> d = a.copy() # a new array object with new data is created
>>> d is a
False
>>> d.base is a # d doesn't share anything with a
False
>>> d[0,0] = 9999
>>> a
array([[ 0, 10, 10, 3],[1234, 10, 10, 7],[ 8, 10, 10, 11]