2.2 使用NumPy库
Python中,NumPy提供了一条高效处理超大数组的途径。大多数Python科学计算库中都在内部使用NumPy处理数组和矩阵操作。在本书中,NumPy被广泛应用,我们在本节介绍它。
2.2.1 准备工作
我们先写一系列语句来操作数组和矩阵,学习如何使用NumPy。目的是让您习惯使用NumPy数组,它也是本书大多数内容的基础。
2.2.2 操作方法
我们先创建一些简单的矩阵和数组。
# Recipe_1a.py
# 导入NumPy库,命名为np
import numpy as np
# 创建数组
a_list = [1,2,3]
an_array = np.array(a_list)
# 指定数据类型
an_array = np.array(a_list,dtype=float)
# 创建矩阵
a_listoflist = [[1,2,3],[5,6,7],[8,9,10]]
a_matrix = np.matrix(a_listoflist,dtype=float)
现在我们可以写一个简单方便的函数来处理NumPy对象。
# Recipe_1b.py
# 一个用来检测给定的NumPy对象的小函数
def display_shape(a):
print
print a
print
print "Nuber of elements in a = %d"%(a.size)
print "Number of dimensions in a = %d"%(a.ndim)
print "Rows and Columns in a ",a.shape
print
display_shape(a_matrix)
换种方式来创建数组。
# Recipe_1c.py
# 换一种方式创建数组
# 1. 使用np.arange来创建NumPy数组
created_array = np.arange(1,10,dtype=float)
display_shape(created_array)
# 2. 使用np.linspace来创建NumPy数组
created_array = np.linspace(1,10)
display_shape(created_array)
# 3. 使用np.logspace来创建NumPy数组
created_array = np.logspace(1,10,base=10.0)
display_shape(created_array)
# 4.在创建数组时指定arange的步长,这是它与np.linspace不同的地方
created_array = np.arange(1,10,2,dtype=int)
display_shape(created_array)
现在我们来看如何创建一些特殊的矩阵。
# Recipe_1d.py
# 创建一个所有元素都为1的矩阵
ones_matrix = np.ones((3,3))
display_shape(ones_matrix)
#创建一个所有元素都为0的矩阵
zeros_matrix = np.zeros((3,3))
display_shape(zeros_matrix)
# 鉴别矩阵
# k参数控制1的索引
# if k =0, (0,0),(1,1,),(2,2) cell values
# 被设置为1,在一个3×3的矩阵中
identity_matrix = np.eye(N=3,M=3,k=0)
display_shape(identity_matrix)
identity_matrix = np.eye(N=3,k=1)
display_shape(identity_matrix)
了解了创建数组和矩阵的知识,我们再看一些整形操作。
# Recipe_1e.py
# 数组的整形
a_matrix = np.arange(9).reshape(3,3)
display_shape(a_matrix)
.
.
.
display_shape(back_array)
接着来看一些矩阵的操作。
# Recipe_1f.py
# 矩阵的操作
a_matrix = np.arange(9).reshape(3,3)
b_matrix = np.arange(9).reshape(3,3)
.
.
.
print "f_matrix, row sum",f_matrix.sum(axis=1)
最后,我们来看一些转置、复制和网格操作。
#Recipe_1g.py
# 转置元素
display_shape(f_matrix[::-1])
.
.
.
zz = zz.flatten()
我们再看看NumPy库里的一些随机数生成例程。
#Recipe_1h.py
# 随机数
general_random_numbers = np.random.randint(1,100, size=10)
print general_random_numbers
.
.
.
uniform_rnd_numbers = np.random.normal(loc=0.2,scale=0.2,size=(3,3))
2.2.3 工作原理
我们先从导入NumPy库开始。
# 导入NumPy库,命名为np
import numpy as np
来看看用NumPy生成数组的多种方式。
# 数组
a_list = [1,2,3]
an_array = np.array(a_list)
# 指定数据类型
an_array = np.array(a_list,dtype=float)
一个数组可以基于列表创建,在前面的示例中,我们声明了一个具有3个元素的列表,然后用np.array()将这个列表转为了NumPy一维数组。如上面代码的最后一行所示,我们也可以指定数据的类型。
了解完数组,再来看看矩阵。
# 矩阵
a_listoflist = [[1,2,3],[5,6,7],[8,9,10]]
a_matrix = np.matrix(a_listoflist,dtype=float)
我们从listoflist里创建了一个矩阵,同样地,我们指定了数据的类型。
在继续之前,我们得先定义display_shape函数,这个函数我们接下来会经常用到。
def display_shape(a):
print
print a
print
print "Nuber of elements in a = %d"%(a.size)
print "Number of dimensions in a = %d"%(a.ndim)
print "Rows and Columns in a ",a.shape
print
所有的NumPy对象都有以下3个属性。
size:给定的NumPy对象里的元素个数。
ndim:维数。
shape:返回一个包含了NumPy对象各个维的长度的元组。
除了打印输出原始的元素,这个函数打印输出上述的3个属性,我们调用这个函数来处理我们之前创建的矩阵。
display_shape(a_matrix)
如图2-1所示,这个矩阵有9个元素,两个维度,最后,我们还能在shape参数里看到维数和每一维的元素个数。在本例中,矩阵有3行3列。
再看另一种创建数组的方法。
created_array = np.arange(1,10,dtype=float)
display_shape(created_array)
NumPy的arange函数返回指定间隔的均匀隔开的数值,本例中,我们所需的是从1到10均匀分布的数值。访问以下URL可以获取更多关于arange的资料。
http://docs.scipy.org/doc/numpy/reference/generated/numpy.arange.html。
# 创建数组的另一种替代办法
created_array = np.linspace(1,10)
display_shape(created_array)
NumPy的linspace和arange类似,差别在于我们需要给出样例的数量值。使用linspace,我们知道在给定的范围里有多少个元素。默认情况下,它返回50个元素。而使用arange,我们还要指定步长。
created_array = np.logspace(1,10,base=10.0)
display_shape(created_array)
NumPy给你提供了一些创建特殊数组的函数。
ones_matrix = np.ones((3,3))
display_shape(ones_matrix)
# 创建一个所有元素均为0的矩阵
zeros_matrix = np.zeros((3,3))
display_shape(zeros_matrix)
ones()和zero()函数分别用来创建全由1和0填充的矩阵,如图2-2所示。
单位矩阵的创建方式如下:
identity_matrix = np.eye(N=3,M=3,k=0)
display_shape(identity_matrix)
参数k控制了1的起始索引值,输出结果如图2-3所示。
identity_matrix = np.eye(N=3,k=1)
display_shape(identity_matrix)
reshape函数可以控制数组的形态。
# 数组转换形态
a_matrix = np.arange(9).reshape(3,3)
display_shape(a_matrix)
通过传递参数−1,我们可以将数组转化为我们所需要的维数,输入结果如图2-4所示。
# 参数-1可以将矩阵转为所需的维数
back_to_array = a_matrix.reshape(-1)
display_shape(back_to_array)
ravel和flatten函数可以用来将矩阵转化为一维的数组,如图2-5所示。
我们再看一些矩阵操作,如两矩阵相加。
c_matrix = a_matrix + b_matrix
再看看矩阵对应元素相乘。
d_matrix = a_matrix * b_matrix
下面是矩阵的乘法操作。
e_matrix = np.dot(a_matrix,b_matrix)
最后,是矩阵的转置。
f_matrix = e_matrix.T
min和max函数可以用来找出矩阵中最小和最大的元素,sum函数则用来对矩阵的行或列进行求和,如图2-6所示。
print
print "f_matrix,minimum = %d"%(f_matrix.min())
print "f_matrix,maximum = %d"%(f_matrix.max())
print "f_matrix, col sum",f_matrix.sum(axis=0)
print "f_matrix, row sum",f_matrix.sum(axis=1)
采用下面的方法将矩阵的元素进行求逆运算。
# 对元素进行逆运算
display_shape(f_matrix[::-1])
copy函数可以复制一个矩阵,方法如下。
# Python中所有元素都能用来引用
# 如果需要复制,可以使用copy命令
f_copy = f_matrix.copy()
最后再看一下mgrid函数。
# Grid命令
xx,yy,zz = np.mgrid[0:3,0:3,0:3]
xx = xx.flatten()
yy = yy.flatten()
zz = zz.flatten()
mgrid函数用来查找m维矩阵中的坐标,在前面的示例中,矩阵是三维的,在每一维中,数值的范围从0到3。我们将xx、yy和zz打印输出出来以帮助理解,如图2-7所示。
我们来看每个数组的第1个元素,在本例的三维矩阵空间中,[0,0,0]是第1个坐标,所有3个数组中的第2个元素[0,0,1]是矩阵空间里的另一个点。据此,使用mgrid函数, 我们能占满三维坐标系统里的所有点。
NumPy提供了一个random模块给我们,可以用来定义产生随机数的规则。我们来看产生随机数的示例。
# 随机数
general_random_numbers = np.random.randint(1,100, size=10)
print general_random_numbers
使用random模块中的randint函数,我们可以生成随机整数。我们需要传递start、end和size等3个参数。本例中,我们的起始值为1,结束值为100,步长为10。我们需要介于1到100的10个随机整数,我们得到的返回结果如图2-8所示。
我们也可以使用其他包来产生随机数,来看看使用normal包产生10个随机数的示例。
uniform_rnd_numbers = np.random.normal(loc=0.2,scale=0.2,size=10)
print uniform_rnd_numbers
我们使用normal包的normal函数来生成随机数。normal包里的loc和scale参数分别指定了均值和标准差两个参数,最后,size参数决定了样本的数量。
通过传递一个行或列的元组,我们也可以产生一个随机的矩阵,示例如下。
uniform_rnd_numbers = np.random.normal(loc=0.2,scale=0.2,size=(3,3))
上面的示例产生了3×3的矩阵,输出结果如图2-9所示。
2.2.4 更多内容
下面的链接提供了一些优秀的NumPy文档,请参见:http://www.numpy.org/。
2.2.5 参考资料
《Analyzing Data -Explore & Wrangle》的第3章中“使用matplotlib进行绘画的诀窍”部分有相关介绍。
《Analyzing Data -Explore & Wrangle》的第3章中“使用Scikit Learn进行机器学习的诀窍”部分有相关介绍。