====== numpy基础知识 ======
===== 学习要点 =====
- 了解NumPy的基本概念
- 了解NumPy的安装及环境测试
- 掌握ndarray的常用属性
- 掌握数组的创建、打印的方法
- 掌握数组对象的各类操作方法
- 熟悉Numpy矩阵的基本知识
----
===== 学习内容 =====
==== 关于NumPy ====
* NumPy是Python语言的一个扩展程序库。支持高端大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。
* NumPy的前身Numeric最早是由Jim Hugunin与其它协作者共同开发,2005年,Travis Oliphant在Numeric中结合了另一个同性质的程序库Numarray的特色,并加入了其它扩展而开发了NumPy。
* NumPy为开放源代码并且由许多协作者共同维护开发。
=== NumPy的安装 ===
NumPy的安装有以下几种常见方法
1. 使用已有的发行版本
如:Anaconda
2. 使用pip安装
python -m pip install --user numpy
3. 如果是Linux
sudo apt install python3-numpy
安装完成后可通过以下方法来测试
>>> import numpy as np
>>> x = np.array([1, 2, 3])
>>> x
==== NumPy基础知识 ====
**1. NumPy的特点:**
* NumPy的主要对象是同构多维数组。
* 同构多维数组是一个元素表(通常是数字),所有类型都相同,由非负整数元组索引。
* 在NumPy中维度(dimension)称为轴( axis)。
**2. ndarray的属性:**
NumPy的数组类被调用ndarray。它也有个叫做array的别名。
注意,numpy.array与标准Python库类array.array不同,后者只处理一维数组并提供较少的功能。
^ 序号 ^ 属性名 ^ 作用 ^
| 1 | ndarray.ndim | 数组的轴(维度)的个数 |
| 2 | ndarray.shape | 数组每个维度的大小,例如一个 n 行 m 列的矩阵的大小为 (n, m) |
| 3 | ndarray.size | 数组元素的总数。这等于 shape 的元素的乘积。 |
| 4 | ndarray.dtype | 一个描述数组中元素类型的对象。 |
| 5 | ndarray.itemsize | 数组中每个元素的字节大小。 |
| 6 | ndarray.data | 该缓冲区包含数组的实际元素(直接读取数组元素)。 |
**3. 数组的创建**
(1)使用empty方法
numpy.empty 方法用来创建一个指定形状(shape)、数据类型(dtype)且未初始化的数组
(2)使用zeros方法
创建指定大小的数组,数组元素以 0 来填充
(3)使用ones方法
创建指定形状的数组,数组元素以 1 来填充
(4)使用array函数从常规Python列表或元组中创建数组
常见错误:调用array的时候传入多个数字参数,而不是提供单个数字的列表类型作为参数 array 还可以将序列的序列转换成二维数组,将序列的序列的序列转换成三维数组
(5)使用函数生成数组
NumPy 提供可迅速生成数列的函数;由于小数精度问题,使用 arange 函数较难预测生成数组的元素数量
如果要指定生成的数组长度,可以使用 linspace 函数
**4. 数组的打印**
NumPy以与嵌套列表类似的方式显示它,显示顺序如下:
* 最后一个轴从左到右打印(行),
* 倒数第二个从上到下打印(列),
* 其余部分也从上到下打印,每个切片用空行分隔。
* 一维数组打印为行,将二维数据打印为矩阵,将三维数据打印为矩数组表。
**5. 数组的通用函数**
NumPy 提供了一些常用的数学函数,例如 sin、cos、exp 等
此类数学函数被称为通用函数(universal functions)
与数学运算类似,通用函数通常是针对数组元素进行操作的。
**6.数组数据的类型**
NumPy最大限度地扩充了原生Python的数据类型,从精确计算的角度出发,使用了不同精度的数据类型。主要包含以下类型。
^ 数据类型 ^ 取值范围 ^
| bool | 用一位存储的布尔类型 |
| inti | 由所在平台决定其精度的整数(一般为int32或int64 ) |
| int8 | 整数,范围为-128~127 |
| int16 | 整数,范围为-32768~32767 |
| int32 | 整数,范围为-231 ~ 231-1 |
| int64 | 整数,范围为-263 ~ 263-1 |
| uint8 | 无符号整数,范围为0~255 |
| uint16 | 无符号整数,范围为0~65535 |
| uint32 | 无符号整数,范围为0~232-1 |
| uint64 | 无符号整数,范围为0~264-1 |
| float | 双精度浮点数(64位),其中用1位表示正负号,用11位表示指数,用52位表示尾数 |
| float16 | 双精度浮点数(16位),其中用1位表示正负号,用5位表示指数,用10位表示尾数 |
| float32 | 双精度浮点数(32位),其中用1位表示正负号,用8位表示指数,用23位表示尾数 |
| float64 | 双精度浮点数(64位),其中用1位表示正负号,用11位表示指数,用52位表示尾数 |
各数据类型间可以使用以下方式进行转换。
np.float64(18)
np.bool(18)
np.int8(18.1)
==== 数组对象的操作 ====
**1. 索引与切片**
(1)关于一维数组
一维数组的索引方法与Python中的list是一致的。
(2)关于多维数组
多维数组的每一个维度都有一个索引,各个维度之间用逗号隔开。
arr=np.arange(10*10).reshape(10,10)
print(arr[2:9:2,:])
(3)布尔索引
可以通过一个布尔数组来索引目标数组,以此找出与布尔数组中值为True的对应的目标数组中的数据。需要注意的是,布尔数组的长度必须与目标数组对应的轴的长度一致。
一维数组的索引
布尔数组中,下标为0,3,4的位置是True,因此将会取出目标数组中对应位置的元素。
>>> arr = np.arange(7)
>>> booling1 = np.array([True,False,False,True,True,False,False])
>>> arr[booling1]
array([0, 3, 4])
二维数组的索引
布尔数组中,下标为0,3,4的位置是True,因此将会取出目标数组中第0,3,4行。
>>> arr = np.arange(28).reshape((7,4))
>>> arr
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23],
[24, 25, 26, 27]])
>>> booling1 = np.array([True,False,False,True,True,False,False])
>>> arr[booling1]
array([[ 0, 1, 2, 3],
[12, 13, 14, 15],
[16, 17, 18, 19]])
可以通过数组的逻辑运算来作为索引(实际上数组的逻辑运算的结果,也就是一个布尔数组)。
假设有一个长度为7的字符串数组,然后对这个字符串数组进行逻辑运算,进而把元素的结果(布尔数组)作为索引的条件传递给目标数组(本质上,和上面那个例子是类似的)。
>>> names = np.array(['Ben','Tom','Ben','Jeremy','Jason','Michael','Ben'])
>>> names == 'Ben'
array([ True, False, True, False, False, False, True], dtype=bool)
>>> arr[names == 'Ben']
array([[ 0, 1, 2, 3],
[ 8, 9, 10, 11],
[24, 25, 26, 27]])
# 在此基础上,我们还可以添加常规的索引和切片操作
>>> arr[names == 'Ben',3]
array([ 3, 11, 27])
>>> arr[names == 'Ben',1:4]
array([[ 1, 2, 3],
[ 9, 10, 11],
[25, 26, 27]])
多个逻辑运算的与和或也是支持的。只需要将逻辑表达式写在索引位置即可。
arr[(names == 'Jason') | (names == 'Tom')]
arr[(names == 'Jason') | (names == 'Tom')] = 0
除此之外,也可以目标数组上做逻辑运算。实际上,这种逻辑运算的到的结果是和目标数组维度和长度都一样的布尔数组。例如,找出arr中大于15的元素,与上面的例子不一样,这个例子返回的结果是一个一维数组。
>>> arr[arr>15]
array([16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27])
(4)花式索引
花式索引是利用元素所在的行、列组成的整数数组进行索引。
arr=np.arange(10*10).reshape(10,10)
row_index=[1,1,2,7]
col_index=[0,2,4,8]
arr[row_index,col_index]
**2. 变换数组的形态**
(1)利用shape和reshape()来改变数组形态
重点:区分两者异同。
shape是方法,调整后回存对象本身
reshape()函数,调整后需要赋值
拓展:
resize()函数,调整后即回存
transpose()函数可以实现二维数组的转置
(2)利用ravel()、flatten()函数展平数组
重点:
ravel()横向展平
flatten()可以选择横向或纵向展平,取决于其参数'F'
(3)堆叠数组
hstack((arr1,arr2)) 水平堆叠,column_stack((arr1,arr2))与之类似
vstack((arr1,arr2)) 垂直堆叠,row_stack((arr1,arr2))与之类似
concatenate((arr1,arr2),axis=0/1) axis为1时水平,为0时垂直
dstack((arr1,arr2))深度叠放
(4)拆分数组
hsplit(arr,n) 横向拆分
vsplit(arr,n) 纵向拆分
split(arr,n,axis) 当axis为1时,横向拆分,为0时,纵向拆分
**3.数组的基本运算**
(1)数组上的算术运算符会应用到元素级别
(2)乘积运算符*在NumPy数组中按元素进行运算。
矩阵乘积可以使用@运算符(在python> = 3.5中)或dot函数或方法执行
(3)某些操作(例如+=和 *=)会更直接更改被操作的矩阵数组而不会创建新矩阵数组。
(4)当使用不同类型的数组进行操作时,结果数组的类型对应于更一般或更精确的数组(称为向上转换的行为)
(5)许多一元操作,例如计算数组中所有元素的总和,都是作为ndarray类的方法实现的。
(6)默认情况下,这些操作适用于数组,就像它是一个数字列表一样,无论其形状如何。但是,通过指定axis 参数,可以沿数组的指定轴应用操作。
**4.NumPy矩阵**
(1)使用mat()函数创建矩阵
(2)使用matrix()函数创建矩阵
(3)使用bmat()函数将分块矩阵进行组合
(4)矩阵的属性
^ 属性 ^ 说明 ^
| T | 返回自身的转置 |
| H | 返回自身的共轭转置 |
| I | 返回自身的逆矩阵 |
| A | 返回自身数据的二维数组的一个视图 |