0. 绪言
学习前先介绍在 Python 中什么是命令行模式和 Python 交互模式
命令行模式
在Windows开始菜单选择“命令提示符”,就进入到命令行模式,它的提示符类似c:/>
Python 交互模式
在命令行模式下敲命令python,就看到类似如下的一堆文本输出,然后就进入到Python交互模式,它的提示符是>>>
在 Python 交互模式下输入exit()
并回车,就退出了Python 交互模式,并回到命令行模式。
我是在交互模式下进行 Python 学习的。对于学习编程,建议多敲代码,多进行实验,才能更深入的了解和更深刻的记忆,个人认为交互式的平台就很适合这个学习的过程。
或者输入ipython
,这样支持变量自动补全,自动缩近,适合熟练掌握之后使用。
下面介绍 NumPy
NumPy 是一个基于 Python 的数值计算库,它弥补了 python 中一些数据处理上的不足,NumPy 提供了两种基本的对象:ndarray(N-dimensional array object)和 ufunc(universal function object)。ndarray 是存储单一数据类 型的多维数组,而 ufunc 则是能够对数组进行处理的函数。
下面我们开始学习用 NumPy 处理数据
1.1 ndarray对象
import numpy as np #导入NumPy函数库
1.2 创建
内容简单,附上学习代码,后面都有注释(python的注释用#
)
>>> a=np.array([1,2,3,4]) #创建一维数组a
>>> a #查看数组a
array([1, 2, 3, 4])
>>> b=np.array([[1,2,3,4],[4,5,6,7],[7,8,9,10]])#创建二维数组b
>>> b
array([[ 1, 2, 3, 4],
[ 4, 5, 6, 7],
[ 7, 8, 9, 10]])
>>> b.dtype ##查看数组b的元素类型
dtype('int32')
>>> a.shape #查看数组a的大小
(4,) #回车后出现这样的字符,说明数组a是一维数组,并且有4个元素
>>> b.shape
(3, 4) #回车后出现这样的字符,说明数组b是二维数组,并且是3行4列
>>> c=b.reshape((4,3)) #创建数组c为数组b的元素顺序不变,但重新排列为4行3列
>>> c
array([[ 1, 2, 3],
[ 4, 4, 5],
[ 6, 7, 7],
[ 8, 9, 10]])
>>> b[0][2]=100 #把数组b中第1行第3列的元素编程100,注意:此时数组c中的3也变成了100
>>> b
array([[ 1, 2, 100, 4],
[ 4, 5, 6, 7],
[ 7, 8, 9, 10]])
>>> c
array([[ 1, 2, 100],
[ 4, 4, 5],
[ 6, 7, 7],
[ 8, 9, 10]])
#通过dtype参数在创建时指定元素类型
>>> np.array([1,2,3,4],dtype=np.float)
array([1., 2., 3., 4.])
>>> np.array([1,2,3,4],dtype=np.double)
array([1., 2., 3., 4.])
>>> np.array([1,2,3,4],dtype=np.complex)
array([1.+0.j, 2.+0.j, 3.+0.j, 4.+0.j])
上面的例子都是先创建一个Python序列,然后通过array函数将其转换为数组,这样做显然效率不高。 因此NumPy提供了很多专门用来创建数组的函数。例如:
>>> np.arange(0,10,1) #np.arange(初值,终值,步长),注意不包括终值
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.linspace(0,10,5) #np.linspace(初值,终值,元素个数)
array([ 0. , 2.5, 5. , 7.5, 10. ])
>>> np.logspace(0,2,10) #产生从10^0到10^2,有10个元素的等比数列
array([ 1. , 1.66810054, 2.7825594 , 4.64158883,
7.74263683, 12.91549665, 21.5443469 , 35.93813664,
59.94842503, 100. ])
还可以写一个 Python 的函数,它将数组下标转换为数组中对应的值,然后使用此函数创建数组:
>>> def f(i):
... return i%4
...
>>> np.fromfunction(f,(10,)) #fromfunction() 应该是np(numpy包)的一个函数。其中第二个参数第二个参数为数组的大小(shape),因为 它支持多维数组,所以第二个参数必须是一个序列,这里是对0-9计算,获取数组元素
array([0., 1., 2., 3., 0., 1., 2., 3., 0., 1.])
注意:python 严格要求缩进,通常是4个空格键。
1.3 存取元素
>>> a = np.arange(10)
>>> a[5] # 用整数作为下标可以获取数组中的某个元素
5
>>> a[3:5] # 用范围作为下标获取数组的一个切片,包括a[3]不包括a[5]
array([3, 4])
>>> a[:5] # 省略开始下标,表示从a[0]开始
array([0, 1, 2, 3, 4])
>>> a[:-1] # 下标可以使用负数,表示从数组后往前数 array([0, 1, 2, 3, 4, 5, 6, 7, 8])
>>> a[2:4] = 100,101 # 下标还可以用来修改元素的值
>>> a
>>> a[1:-1:2] # 范围中的第三个参数表示步长,2表示隔一个元素取一个元素
array([ 1, 101, 5, 7])
>>> a[::-1] # 省略范围的开始下标和结束下标,步长为-1,整个数组头尾颠倒
array([ 9, 8, 7, 6, 5, 4, 101, 100, 1, 0])
>>> a[5:1:-2] # 步长为负数时,开始下标必须大于结束下标array([ 5, 101])
和Python的列表序列不同的是,通过下标范围获取的新的数组是原始数组的一个视图。它与原始数组共享 同一块数据空间。
两种存取元素的高级方法:
使用整数序列
当使用整数序列对数组元素进行存取时,将使用整数序列中的每个元素作为下标,整数序列可以是列 表或者数组。使用整数序列作为下标获得的数组不和原始数组共享数据空间。
>>> x = np.arange(10,1,-1)
>>> x
array([10, 9, 8, 7, 6, 5, 4, 3, 2])
>>> x[[3, 3, 1, 8]] #获取x中的下标为3, 3, 1, 8的4个元素,组成一个新的数组
array([7, 7, 9, 2])
>>> b = x[np.array([3,3,-3,8])] #下标可以是负数
>>> b[2] = 100
>>> b
array([7, 7, 100, 2])
>>> x #由于b和x不共享数据空间,因此x中的值并没有改变
array([10, 9, 8, 7, 6, 5, 4, 3, 2])
>>> x[[3,5,1]] = -1, -2, -3 #整数序列下标也可以用来修改元素的值
>>> x
array([10, -3, 8, -1, 6, -2, 4, 3, 2])
使用布尔数组
>>> x = np.arange(5,0,-1)
>>> x
>>> x[np.array([True, False, True, False, False])] # 布尔数组中下标为0,2的元素为True,因此获取x中下标为0,2的元素
array([5, 3])
>>> x[[True, False, True, False, False]] # 如果是布尔列表,则把True当作1, False当作0,按照整数序列方式获取x中的元素
array([4, 5, 4, 5, 5])
>>> x[np.array([True, False, True, True])] # 布尔数组的长度不够时,不够的部分都当作False array([5, 3, 2])
>>> x[np.array([True, False, True, True])] = -1, -2, -3 # 布尔数组下标也可以用来修改元素
>>> x
array([-1, 4, -2, -3, 1])
1.4 多维数组
多维数组的建立方式例如:
>>> np.arange(0, 60, 10).reshape(-1, 1) + np.arange(0, 6)
array([[ 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]])
1.5 结构数组
>>>persontype = np.dtype({ 'names':['name', 'age', 'weight'], 'formats':['S32','i', 'f']})
>>> #创建一个dtype对象persontype,通过其字典参数描述结构类型的各个字段。字典有两个关键字:names,formats。每个关键字对应的值都是一个列表。names定义结构中的每个字段名,而formats则定义每个字段的类型
>>>a = np.array([("Zhang",32,75.5),("Wang",24,65.2)], dtype=persontype)
>>> #调用array函数创建数组,元素类型结构为persontype
>>> a.dtype #查看结构数组a的类型
dtype([('name', '|S32'), ('age', '<i4'), ('weight', '<f4')])
>>> a[0] #查看数据
('Zhang', 32, 75.5)
>>> a[0]["name"] #获取对应字符串
'Zhang'
1.6 内存结构
数组的维数、大小等信息都保存在ndarray数组对象的数据结构中,这个结构引用两个对象:一块用于保存数据的存储区域和一个用于描述元素类型 的dtype对象。