本文是在学习numpy 的时候做的笔记,记录了numpy 的常用操作,方便用的时候查找。
1. 什么是NumPy,它有什么用
NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。
简单来说 NumPy 就是提供一个数组、矩阵存储和运算的库。与Python 自带的list 相似,不过速度更快,功能更多。
2. NumPy 的数据类型
2.1 ndarray–NumPy 的主要数据对象
我们所说的多维数组或者矩阵,在 NumPy 中的存放对象是 ndarray ,ndarray 也就是 n 维数组的意思。
ndarray 对象内部由以下内容组成:
- 一个指向数据 (内存中的一块区域)的指针。
- 元素的数据类型,用来确定一个元素占多大空间。
- 一个表示数组形状(shape)的元祖,表示各维度的大小。
- 一个跨度元组(stride),其中的整数指的是为了前进到当前维度下一个元素需要”跨过”的字节数。(方便内存区域中直接取数据)
创建一个 ndarray 只需调用 NumPy 的 array 函数即可:
numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
参数说明:
名称 | 描述 |
---|---|
object | 数组或嵌套的数列 |
dtype | 数组元素的数据类型,可选 |
copy | 对象是否需要复制,可选 |
order | 创建数组的样式,C为行方向,F为列方向,A为任意方向(默认) |
subok | 默认返回一个与基类类型一致的数组 |
ndmin | 指定生成数组的最小维度 |
实例:
1 | import numpy as np |
2.2 ndarray 中元素的数据类型
numpy 支持的数据类型比 Python 内置的类型要多很多,基本上可以和 C 语言的数据类型对应上,其中部分类型对应为 Python 内置的类型。下表列举了常用 NumPy 基本类型。
名称 | 描述 |
---|---|
bool_ | 布尔型数据类型(True 或者 False) |
int_ | 默认的整数类型(类似于 C 语言中的 long,int32 或 int64) |
intc | 与 C 的 int 类型一样,一般是 int32 或 int 64 |
intp | 用于索引的整数类型(类似于 C 的 ssize_t,一般情况下仍然是 int32 或 int64) |
int8 | 字节(-128 to 127) |
int16 | 整数(-32768 to 32767) |
int32 | 整数(-2147483648 to 2147483647) |
int64 | 整数(-9223372036854775808 to 9223372036854775807) |
uint8 | 无符号整数(0 to 255) |
uint16 | 无符号整数(0 to 65535) |
uint32 | 无符号整数(0 to 4294967295) |
uint64 | 无符号整数(0 to 18446744073709551615) |
float_ | float64 类型的简写 |
float16 | 半精度浮点数,包括:1 个符号位,5 个指数位,10 个尾数位 |
float32 | 单精度浮点数,包括:1 个符号位,8 个指数位,23 个尾数位 |
float64 | 双精度浮点数,包括:1 个符号位,11 个指数位,52 个尾数位 |
complex_ | complex128 类型的简写,即 128 位复数 |
complex64 | 复数,表示双 32 位浮点数(实数部分和虚数部分) |
complex128 | 复数,表示双 64 位浮点数(实数部分和虚数部分) |
numpy 的数值类型实际上是 dtype 对象的实例,并对应唯一的字符,包括 np.bool_,np.int32,np.float32,等等。
这些类型记住几个常用就行,一般就是int和float。
引用方法如:np.int32
1 | import numpy as np |
其中,直接写 ‘int’,就等于 ‘int32’ ;’float’ = ‘float64’
重点:修改数据类型
1.直接硬改数据类型导致数组值变化
如:
1 | import numpy as np |
上面修改完a 的数据类型,a 数组的值和元素个数都变了。仔细想想可以发现,ndarray是根据数组中dtype 的信息来解析内存中的数据,所以64位int改成32位int后元素个数会翻2倍。如果改成 ‘int16’ 型,将会变成12个元素。
当然float 强转成int 型数值也会变化。从文本中读入数据的类型默认是float64。
2. 想要改变数据类型而不改变数组元素的值,要用数组的 aseype() 函数。
1 | import numpy as np |
2.3 ndarray 对象的属性
ndarray 对象的属性,常用的有:数组形状shape、元素个数size、元素数据类型dtype。
属性 | 说明 |
---|---|
ndarray.ndim | 秩,即轴的数量或维度的数量 |
ndarray.shape | 数组的维度,对于矩阵,n 行 m 列 |
ndarray.size | 数组元素的总个数,相当于 .shape 中 n*m 的值 |
ndarray.dtype | ndarray 对象的元素类型 |
ndarray.itemsize | ndarray 对象中每个元素的大小,以字节为单位 |
ndarray.flags | ndarray 对象的内存信息 |
ndarray.real | ndarray元素的实部 |
ndarray.imag | ndarray 元素的虚部 |
ndarray.data | 包含实际数组元素的缓冲区,由于一般通过数组的索引获取元素,所以通常不需要使用这个属性。 |
3. 创建ndarray数组
3.1 利用函数创建空、全0、全1数组
1 | x = np.empty([3,2], dtype = int) # 默认float64型 |
3.2 利用列表、元组创建数组
函数:np.array() 、 np.asarray
两个函数用法差别不大。
未指定数据类型时,如果传入的数组中全是整数,则ndarray 默认int32 ;如果有小数,则默认float64;
1 | import numpy as np |
3.3 利用可迭代对象创建数组
函数:numpy.fromiter(iterable, dtype, count=-1)
1 | import numpy as np |
3.4 从数值范围创建数组,创建等比、等差数组
(1)从一定范围创建数组
函数:numpy.arange(start, stop, step, dtype)
参数:起始值,终止值,步长,数据类型。起始值默认为0,数组不包含终止值。
1 | x = np.arange(5) |
(2)创建等差数列
numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
参数:
参数 | 描述 |
---|---|
start |
序列的起始值 |
stop |
序列的终止值,如果endpoint 为true ,该值包含于数列中 |
num |
要生成的等步长的样本数量,默认为50 |
endpoint |
该值为 true 时,数列中中包含stop 值,反之不包含,默认是True。 |
retstep |
如果为 True 时,生成的数组中会显示间距,反之不显示。 |
dtype |
ndarray 的数据类型 |
linspace函数与arange函数不同,前者是用起始、终止和元素个数,后者是用起始终止和步长。
1 | a = np.linspace(1,10,10) # 创建1-10,十个数 |
(3)创建等比数列
函数:np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
参数 | 描述 |
---|---|
start |
序列的起始值为:base ** start |
stop |
序列的终止值为:base ** stop。如果endpoint 为true ,该值包含于数列中 |
num |
要生成的等步长的样本数量,默认为50 |
endpoint |
该值为 true 时,数列中中包含stop 值,反之不包含,默认是True。 |
base |
对数 log 的底数。 |
dtype |
ndarray 的数据类型 |
与创建等差数列的参数不同,start=1、stop=5 范围是10-100000。
1 | # 从1-2的9次方,十个数 |
4. 索引、切片
用来选取某些行、列,这是numpy最常用的操作。
实际中比较常用的有普通索引和布尔索引,花式索引偶尔也用得到。
索引方式有:
- 普通索引。a[2:3:7]
- 整数数组索引。要取得元素序号存放于另一个数组中。
- 布尔索引。[true, false, true, false] 选取第1、3个元素。或者 x[x > 5],这样用
- 花式索引。传入行号数组。
4.1 普通索引
冒号作用是 start : stop : step
。在某一维度内选。只有1个冒号时,表示step默认为1;省略start,即默认start为0;省略stop,即默认后面所有。
逗号的作用是 行, 列
。逗号分隔不同维度。
1 | # 一维,用不到逗号 |
1 | # 多维(二维) |
4.2 整数数组索引
需要选取元素的位置是放在一个数组中。
1 | x = np.array([[1, 2], [3, 4], [5, 6]]) |
4.3 布尔索引
True为选取,False为不选取。
1 | x=np.array([[0,1,2],[3,4,5],[6,7,8],[9,10,11]]) |
布尔索引也常用来过滤空值、复数等。
1 | # 过滤空值,~表示取反 |
4.4 花式索引
花式索引也是传入整数数组,选取某些行、某些列,传入负数时时倒着的顺序。
1 | x=np.arange(32).reshape((8,4)) |
5. NumPy 广播机制
也就是当两个形状不同的数组进行数值计算时,会触发广播机制,小的数组会自动想大的对齐。
1 | a = np.array([[ 0, 0, 0], |
6. 迭代数组
1 | a = np.arange(6).reshape(2,3) |
迭代与内存中是行优先存放还是列优先存放有关,也可以选择行列迭代顺序。
7. 数组操作
这里只列出了最常用的方法。
7.1 修改形状 reshape
1 | a = np.arange(8) |
7.2 翻转数组,转置
可以直接a.T ,也可以np.transpose(a) ,都是转置操作。
1 | a = np.arange(12).reshape(3,4) |
7.3 连接数组
(1)numpy.concatenate((a1, a2, …), axis)
连接数组,axis参数是指定沿哪个轴连接,默认为0,行连接。
1 | a = np.array([[1,2],[3,4]]) |
(2)numpy.stack(arrays, axis)
输入的数组需要有相同的形状,功能与concatenate 函数相同。
(3)numpy.hstack、numpy.vstack
stack 函数的变体,水平堆叠和垂直堆叠。
7.4 分割数组
函数 | 数组及操作 |
---|---|
split | 将一个数组分割为多个子数组 |
hsplit | 将一个数组水平分割为多个子数组(按列) |
vsplit | 将一个数组垂直分割为多个子数组(按行) |
(1)numpy.split(ary, indices_or_sections, axis)
沿特定的轴将数组分割为子数组。
参数:
ary
:被分割的数组indices_or_sections
:果是一个整数(3),就用该数平均切分(平均切成3份),如果是一个数组,[2, 4],就在第二个和第四个元素位置切开(左开右闭)。axis
:沿着哪个维度进行切向,默认为0,横向切分。为1时,纵向切分。
1 | a = np.arange(9) #[0 1 2 3 4 5 6 7 8] |
(2)numpy.hsplit(array, n)
将数组竖着切成相等的 n 份。
1 | import numpy as np |
(3)numpy.vsplit(array, n)
将数组横着切成相等的 n 份。
8. 数组元素的添加与删除
函数 | 元素及描述 |
---|---|
append | 将值添加到数组末尾 |
insert | 沿指定轴将值插入到指定下标之前 |
delete | 删掉某个轴的子数组,并返回删除后的新数组 |
unique | 查找数组内的唯一元素 |
8.1 追加 append
函数:numpy.append(arr, values, axis=None)
在数组的末尾添加值。 追加操作会分配整个数组,并把原来的数组复制到新数组中。 此外,输入数组的维度必须匹配否则将生成ValueError。
参数:
arr
:输入数组values
:要向arr
添加的值,需要和arr
形状相同(除了要添加的轴)axis
:默认为 None。当axis无定义时,是横向加成,返回总是为一维数组!当axis有定义的时候,分别为0和1的时候。当axis有定义的时候,分别为0和1的时候(列数要相同)。当axis为1时,数组是加在右边(行数要相同)。
1 | a = np.array([[1,2,3],[4,5,6]]) |
8.2 指定位置插入 insert
函数:numpy.insert(arr, obj, values, axis)
在数组指定位置插入元素。
参数:
arr
:输入数组obj
:在其之前插入值的索引,即插入在第几个数后values
:要插入的值,如果是单值,则会被广播axis
:沿着它插入的轴,如果未提供,则输入数组会被展开
1 | a = np.array([[1,2],[3,4],[5,6]]) |
8.3 删除 delete
函数:Numpy.delete(arr, obj, axis)
删除某些行、列。
参数:
arr
:输入数组obj
:可以被切片,整数或者整数数组,表明要从输入数组删除的子数组。如[0,1]表示第1、2列;1表示删除第二列。axis
:沿着它删除给定子数组的轴,如果未提供,则输入数组会被展开
1 | a = np.arange(12).reshape(3,4) |
8.4 去重 unique
函数:numpy.unique(arr, return_index, return_inverse, return_counts)
数组去重,可以返回多种形式,比如去重后的数组、重复值的索引、重复的个数等。
参数:
arr
:输入数组,如果不是一维数组则会展开return_index
:如果为true
,返回新列表元素在旧列表中的位置(下标),并以列表形式储return_inverse
:如果为true
,返回旧列表元素在新列表中的位置(下标),并以列表形式储return_counts
:如果为true
,返回去重数组中的元素在原数组中的出现次数