Day28: NumPy(Numerical Python)
本文参考:
https://www.runoob.com/numpy/numpy-tutorial.html
https://gitbook.cn/m/mazi/columns/5e37978dec8d9033cf916b5d/topics/5e3bceadec8d9033cf924665
- NumPy 是一个运行速度非常快的数学库,主要用于数组计算,包含:
- 一个强大的N维数组对象 ndarray
- 广播功能函数
- 整合 C/C++/Fortran 代码的工具
- 线性代数、傅里叶变换、随机数生成等功能
如果不会用matlab,那么就可以不用学了,用Numpy+SciPy+ Matplotlib替代,在数据科学或者机器学习中被广泛使用。下面先看numpy.
- SciPy 是一个开源的 Python 算法库和数学工具包。
SciPy 包含的模块有最优化、线性代数、积分、插值、特殊函数、快速傅里叶变换、信号处理和图像处理、常微分方程求解和其他科学与工程中常用的计算。
- Matplotlib 是 Python 编程语言及其数值数学扩展包 NumPy 的可视化操作界面。
它为利用通用的图形用户界面工具包,如 Tkinter, wxPython, Qt 或 GTK+ 向应用程序嵌入式绘图提供了应用程序接口(API)。
NumPy安装
pip install numpy scipy matplotlib
验证:
>>> from numpy import * >>> eye(5) # 生成对角矩阵 array([[1., 0., 0., 0., 0.], [0., 1., 0., 0., 0.], [0., 0., 1., 0., 0.], [0., 0., 0., 1., 0.], [0., 0., 0., 0., 1.]]) >>>
NumPy Ndarray 对象
N 维数组对象 ndarray,它是一系列同类型数据的集合,以 0 下标为开始进行集合中元素的索引。
- 多维数组
- 存放同类型元素
- 每个元素在内存中都有相同存储大小的区域
创建一个ndarry的函数原型:
numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
参数说明:
名称 | 描述 |
---|---|
object | 数组或嵌套的数列 |
dtype | 数组元素的数据类型,可选 |
copy | 对象是否需要复制,可选 |
order | 创建数组的样式,C为行方向,F为列方向,A为任意方向(默认) |
subok | 默认返回一个与基类类型一致的数组 |
ndmin | 指定生成数组的最小维度 |
创建数组:
import numpy as np a = np.array([1,2,3]) print(a) b = np.array([[1,2],[3,4]]) print(b) output: [1 2 3] [[1 2] [3 4]]
numpy 数据类型
- numpy 支持的数据类型比 Python 内置的类型要多很多
- numpy 的数值类型实际上是 dtype 对象的实例,并对应唯一的字符
名称 | 描述 |
---|---|
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 类的实例)用来描述与数组对应的内存区域是如何使用.
创建dtype 对象函数原型:
numpy.dtype(object, align, copy)
- object - 要转换为的数据类型对象
- align - 如果为 true,填充字段使其类似 C 的结构体。
- copy - 复制 dtype 对象 ,如果为 false,则是对内置数据类型对象的引用
# 使用标量类型 dt = np.dtype(np.int32) print(dt) # int8, int16, int32, int64 四种数据类型可以使用字符串 'i1', 'i2','i4','i8' 代替 dt = np.dtype('i8') print(dt) # 字节顺序标注 dt = np.dtype('<i4') # < 意味着小端法(最小值存储在最小的地址,即低位组放在最前面)。> 意味着大端法(最重要的字节存储在最小的地址,即高位组放在最前面)。 print(dt) output: int32 int64 int32
下面实例展示结构化数据类型的使用,类型字段和对应的实际类型将被创建。
# 首先创建结构化数据类型 dt = np.dtype([('age',np.int8)]) print(dt) # 将数据类型应用于 ndarray 对象 dt = np.dtype([('age',np.int8)]) a = np.array([(10,),(20,),(30,)], dtype = dt) print(a) # 类型字段名可以用于存取实际的 age 列 dt = np.dtype([('age',np.int8)]) a = np.array([(10,),(20,),(30,)], dtype = dt) print(a['age']) # 结构化数据类型 student,包含字符串字段 name,整数字段 age,及浮点字段 marks,并将这个 dtype 应用到 ndarray 对象。 student = np.dtype([('name','S20'), ('age', 'i1'), ('marks', 'f4')]) print(student) a = np.array([('abc', 21, 50),('xyz', 18, 75)], dtype = student) print(a) output: [('age', 'i1')] [(10,) (20,) (30,)] [10 20 30] [('name', 'S20'), ('age', 'i1'), ('marks', '<f4')] [(b'abc', 21, 50.) (b'xyz', 18, 75.)]
结构化数据类型就是 类型字段 对应 实际类型,其实很好理解,我希望数据有方便地别称来表示他在我的使用中的意义(类型字段),同时在计算机中他需要固定的类型去存储和做各种计算(实际类型)。
NumPy 数组的一些基本属性
比较重要 ndarray 对象属性有:
属性 | 说明 |
---|---|
ndarray.ndim | 秩,即轴的数量或维度的数量 |
ndarray.shape | 数组的维度,对于矩阵,n 行 m 列 |
ndarray.size | 数组元素的总个数,相当于 .shape 中 n*m 的值 |
ndarray.dtype | ndarray 对象的元素类型 |
ndarray.itemsize | ndarray 对象中每个元素的大小,以字节为单位,一个字节8个bit |
ndarray.flags | ndarray 对象的内存信息 |
ndarray.real | ndarray元素的实部 |
ndarray.imag | ndarray 元素的虚部 |
ndarray.data | 包含实际数组元素的缓冲区,由于一般通过数组的索引获取元素,所以通常不需要使用这个属性。 |
- NumPy 也提供了 reshape 函数来调整数组大小。
a = np.arange(24) print (a.ndim) # a 现只有一个维度 print(a) # 现在调整其大小 b = a.reshape(2,4,3) # b 现在拥有三个维度 print (b.ndim) print(b) output: 1 [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23] 3 [[[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] [[12 13 14] [15 16 17] [18 19 20] [21 22 23]]]
- ndarray.shape 也可以用于调整数组大小。
a = np.array([[1,2,3],[4,5,6]]) print(a) print (a.shape) a.shape = (3,2) print(a) output: [[1 2 3] [4 5 6]] (2, 3) [[1 2] [3 4] [5 6]]
- 内存信息长森么样
a = np.array([1,2,3,4,5]) print (a.flags) output: C_CONTIGUOUS : True F_CONTIGUOUS : True OWNDATA : True WRITEABLE : True ALIGNED : True WRITEBACKIFCOPY : False UPDATEIFCOPY : False
NumPy 创建数组
创建初始化数组
上面说过创建数组的原语,用底层 ndarray 构造器来创建,但除此之外,python还提供了很多的方法:
1)numpy.empty
numpy.empty(shape, dtype = float, order = 'C')
- 用来创建一个指定形状(shape)、数据类型(dtype)且未初始化的数组。
- order有"C"和"F"两个选项,分别代表,行优先和列优先,在计算机内存中的存储元素的顺序。'C' 用于 C 的行数组,或者 'F' 用于 FORTRAN 的列数组
import numpy as np x = np.empty([3,2], dtype = int,order = 'F') print (x) y = np.empty([3,2], dtype = int,order = 'C') print (x) output: [[25775744192 0] [ 6445641960 0] [ 0 0]] [[25775744192 0] [ 6445641960 0] [ 0 0]]
- 上面输出的随机值是因为数组未初始化,所以 emmm ... np.empty()
2)numpy.zeros
numpy.zeros(shape, dtype = float, order = 'C')
和empty不同的是,数据以0来填充
3)numpy.ones
numpy.ones(shape, dtype = None, order = 'C')
数据以1来填充
从已有的数组来创建数组
4)numpy.asarray
numpy.asarray(a, dtype = None, order = None)
- a, 任意形式的输入参数,可以是,列表, 列表的元组, 元组, 元组的元组, 元组的列表,多维数组

import numpy as np x = [1,2,3] a = np.asarray(x) print (a) x = (1,2,3) a = np.asarray(x) print (a) x = [(1,2,3),(4,5)] a = np.asarray(x) print (a) x = [1,2,3] a = np.asarray(x, dtype = float) print (a) output: [1 2 3] [1 2 3] [(1, 2, 3) (4, 5)] [1. 2. 3.]
5)numpy.frombuffer
- 用于实现动态数组。
- 接受 buffer 输入参数,以流的形式读入转化成 ndarray 对象:
numpy.frombuffer(buffer, dtype = float, count = -1, offset = 0)
参数 | 描述 |
---|---|
buffer | 可以是任意对象,以流的形式读入。 |
dtype | 返回数组的数据类型,可选 |
count | 读取的数据数量,默认为-1,读取所有数据。 |
offset | 读取的起始位置,默认为0。 |
python3栗子:
import numpy as np s = b'Hello World' a = np.frombuffer(s, dtype = 'S1') print (a) output: [b'H' b'e' b'l' b'l' b'o' b' ' b'W' b'o' b'r' b'l' b'd']
6)numpy.fromiter
iter,想到了什么,可迭代对象。从可迭代对象中建立 ndarray 对象,返回一维数组
numpy.fromiter(iterable, dtype, count=-1)
栗子:
import numpy as np # 使用 range 函数创建列表对象 list=range(5) it=iter(list) # 使用迭代器创建 ndarray x=np.fromiter(it, dtype=int) print(x) output: [0 1 2 3 4]
从数值范围创建数组
7)numpy.arange
numpy.arange(start, stop, step, dtype)
numpy 包中的使用 arange 函数创建数值范围并返回 ndarray 对象:
参数说明:
参数 | 描述 |
---|---|
start |
起始值,默认为0 |
stop |
终止值(不包含) |
step |
步长,默认为1 |
dtype |
返回ndarray 的数据类型,如果没有提供,则会使用输入数据的类型。 |
import numpy as np # 生成0-4一维数组 x = np.arange(5) print (x) # 设置了起始值、终止值及步长 x = np.arange(10,20,2) print (x) output: [0 1 2 3 4] [10 12 14 16 18]
8)numpy.linspace
创建一个一维数组,数组是一个等差数列构成的,格式如下:
np.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 的数据类型 |
- 没有地方设置步长哦,由起始、终止、个数决定
import numpy as np a = np.linspace(1,10,10) print(a) # 元素全部是1的等差数列 a = np.linspace(1,1,10) print(a) # 将 endpoint 设为 false,即不包含终止值 a = np.linspace(10, 20, 5, endpoint = False) print(a) # 显示间距 a = np.linspace(10, 20, 5, endpoint = False,retstep= True) print(a) output: [ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.] [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] [10. 12. 14. 16. 18.] (array([10., 12., 14., 16., 18.]), 2.0)
9)numpy.logspace
用于创建一个于等比数列。格式如下:
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 的数据类型 |
- base 参数意思是取对数的时候 log 的下标。默认值10
import numpy as np # 默认底数是 10 a = np.logspace(1.0, 2.0, num = 10) print (a) # 底数设置为2 a = np.logspace(0,9,10,base=2) print (a) output: [ 10. 12.91549665 16.68100537 21.5443469 27.82559402 35.93813664 46.41588834 59.94842503 77.42636827 100. ] [ 1. 2. 4. 8. 16. 32. 64. 128. 256. 512.]
NumPy 切片和索引
切片和索引
ndarray对象也可以像list对象一样,使用索引和切片操作来进行访问或者修改。
python有内置一个slice函数,设置 start, stop 及 step 参数,从原数组中切割出一个新数组。
import numpy as np a = np.arange(7) s = slice(1,7,2) print(a[s]) print(s) a[s][2] = 7 print(a) output: [1 3 5] # 这个是新数组 slice(1, 7, 2) [0 1 2 3 4 7 6]
切片:
import numpy as np a = np.arange(7) b = a[1:7:2] print(b) print(a) b[2] = 7 print(a) output: [1 3 5] [0 1 2 3 4 5 6] [0 1 2 3 4 7 6]
这样操作的话,可见改变了b的值,相应的a的值也被改变了。
p.s.
- 通过冒号分隔切片参数 start:stop:step 来进行切片操作
- 如果只放置一个参数,如 [2],将返回与该索引相对应的单个元素。
- 如果为 [2:],表示从该索引开始以后的所有项都将被提取。
- 如果使用了两个参数,如 [2:7],那么则提取两个索引(不包括停止索引)之间的项
小知识,多维数组同样可以使用切片啊😁
import numpy as np a = np.array([[1,2,3],[4,5,6],[8,9,10]]) print(a) # 从某个索引处开始切割 print('从数组索引 a[1:] 处开始切割') print(a[1:]) # 使用一个参数 print('使用一个参数a[2]') print(a[2]) # 使用2个参数 print('使用2个参数a[0:2]') print(a[0:2]) output: [[ 1 2 3] [ 4 5 6] [ 8 9 10]] 从数组索引 a[1:] 处开始切割 [[ 4 5 6] [ 8 9 10]] 使用一个参数a[2] [ 8 9 10] 使用2个参数a[0:2] [[1 2 3] [4 5 6]]
小知识,切片还可以用省略号来操作😁
如果在行(列)位置使用省略号,它将返回包含行(列)中元素的 ndarray。
import numpy as np a = np.array([[1,2,3],[4,5,6],[8,9,10]]) print(a) # 返回第2行元素 print('返回第2行元素') print(a[1,...]) # 返回第2列元素 print('返回第2列元素') print(a[...,1]) # 返回第2列之后的所有元素 print('返回第2列之后的所有元素') print(a[...,1:]) output: [[ 1 2 3] [ 4 5 6] [ 8 9 10]] 返回第2行元素 [4 5 6] 返回第2列元素 [2 5 9] 返回第2列之后的所有元素 [[ 2 3] [ 5 6] [ 9 10]]
上面大部分是关于切片的操作,来看一下在NumPy中,它有何表现:
NumPy 高级索引
除了之前看到的用整数和切片的索引外,数组可以由整数数组索引、布尔索引及花式索引三种方式:
1)整数数组索引
import numpy as np x = np.array([[1,2],[3,4],[5,6]]) y = x[[0,1,2],[0,1,0]] # 看成匹配行和列 (0行,0列)+ (1行,1列)+ (2行,0列) print (y) output: [1 4 5]
把单独的元素pick出来:
import numpy as np x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]]) print ('我们的数组是:' ) print (x) print ('\n') rows = np.array([[0,0],[3,3]]) print('rows:\n',rows) cols = np.array([[0,2],[0,2]]) print('cols:\n',cols) y = x[rows,cols] print ('这个数组的四个角元素是:(0行,0列)(0,2)(3,0)(3,2)') print (y) output: 我们的数组是: [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] rows: [[0 0] [3 3]] cols: [[0 2] [0 2]] 这个数组的四个角元素是:(0行,0列)(0,2)(3,0)(3,2) [[ 0 2] [ 9 11]]
返回的结果是ndarray 对象!
试试在ndarray 对象上使用索引和切片:
import numpy as np x = np.array([[0,1,2],[3,4,5],[6,7,8],[9,10,11]]) print ('数组是:' ) print (x) print ('\n') b = x[1:3, 1:3] c = x[1:3,[1,2]] d = x[...,1:] print(b) #(第1行,第1列) (1,2) (2,1),(2,2) print ('\n') print(c) #(第1行,第1列) (1,2) (2,1),(2,2) print ('\n') print(d) #(遍历所有行,遍历【1,2】列) output: 数组是: [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] [[4 5] [7 8]] [[4 5] [7 8]] [[ 1 2] [ 4 5] [ 7 8] [10 11]]
2)布尔索引
布尔索引通过布尔运算(如:比较运算符)来获取符合指定条件的元素的数组。
# 布尔索引 # 获取大于 5 的元素: import numpy as np x = np.array([[0,1,2],[3,4,5],[6,7,8],[9,10,11]]) print ('我们的数组是:') print (x) print ('\n') print('x中大于5的元素是:') print(x[x>5]) output: 我们的数组是: [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] x中大于5的元素是: [ 6 7 8 9 10 11]
用来过滤元素:
import numpy as np a = np.array([np.nan, 1,2,np.nan,3,4,5]) # np.nan是一个float类型的数据 None是一个NoneType类型,nan 不是一个数 print(a) print(a[~np.isnan(a)])# 过滤nan b = np.array([1, 2+6j, 5, 3.5+5j]) print(b) print (b[np.iscomplex(b)]) # 过滤实数or复数 output: [nan 1. 2. nan 3. 4. 5.] [1. 2. 3. 4. 5.] [1. +0.j 2. +6.j 5. +0.j 3.5+5.j] [2. +6.j 3.5+5.j]
3)花式索引
花式索引根据索引数组的值作为目标数组的某个轴的下标来取值。
对于使用一维整型数组作为索引,如果目标是一维数组,那么索引的结果就是对应下标的行,
如果目标是二维数组,那么就是对应位置的元素。
花式索引跟切片不一样,它总是将数据复制到新数组中。
- 注意: [[]]
# 花式索引 import numpy as np x = np.arange(32).reshape((8,4)) print(x) print('\n') # 顺序索引数组 print(x[[4,2,1,7]]) print('\n') # 倒序索引数组 print(x[[-4,-2,-1,-7]]) print('\n') # 多个索引数组(要使用np.ix_) print (x[np.ix_([1,5,7,2],[0,3,1,2])]) # (1,0)(1,3)(1,1)(1,2) ... output: [[ 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] [28 29 30 31]] [[16 17 18 19] [ 8 9 10 11] [ 4 5 6 7] [28 29 30 31]] [[16 17 18 19] [24 25 26 27] [28 29 30 31] [ 4 5 6 7]] [[ 4 7 5 6] [20 23 21 22] [28 31 29 30] [ 8 11 9 10]]
NumPy 广播(Broadcast)
一般数组的运算,通常在相应的元素上进行。
和一般的数组乘法不同,array的乘需要shape相同:即满足 a.shape == b.shape,那么 a*b 的结果就是 a 与 b 数组对应位相乘。这要求维数相同,且各维度的长度相同。
import numpy as np a = np.array([1,2,3,4]) b = np.array([10,20,30,40]) print(a,b) c = a * b print (c) output: [1 2 3 4] [10 20 30 40] [ 10 40 90 160] ---------------------------分割线--------------------------------- import numpy as np a = np.array([1,2,3,4]) b = np.array([10,20,30,40]).reshape((4,1)) print(a,b) c = a * b print (c) output: [1 2 3 4] [[10] [20] [30] [40]] [[ 10 20 30 40] [ 20 40 60 80] [ 30 60 90 120] [ 40 80 120 160]]
为什么会这样?
当运算中的 2 个数组的形状不同时,numpy 将自动触发广播机制!!!
广播的规则:
- 让所有输入数组都向其中形状最长的数组看齐,形状中不足的部分都通过在前面加 1 补齐。
- 输出数组的形状是输入数组形状的各个维度上的最大值。
- 如果输入数组的某个维度和输出数组的对应维度的长度相同或者其长度为 1 时,这个数组能够用来计算,否则出错。
- 当输入数组的某个维度的长度为 1 时,沿着此维度运算时都用此维度上的第一组值。
简单理解:对两个数组,分别比较他们的每一个维度(若其中一个数组没有当前维度则忽略),满足:
- 数组拥有相同形状。
- 当前维度的值相等。
- 当前维度的值有一个是 1。
若条件不满足,抛出 "ValueError: frames are not aligned" 异常。
NumPy 迭代数组
NumPy 迭代器对象 numpy.nditer 提供了一种灵活访问一个或者多个数组元素的方式。
# NumPy 迭代器对象 numpy.nditer 提供了一种灵活访问一个或者多个数组元素的方式。 import numpy as np a = np.arange(6).reshape(2,3) print ('我们的数组是:') print (a) print ('\n') print ('迭代输出元素:') # 默认一行一行迭代访问 for x in np.nditer(a): print(x,end=',') print ('\n') # 一列一列访问 for x in np.nditer(a.T.copy(order='C')): print (x, end="," ) output: 我们的数组是: [[0 1 2] [3 4 5]] 迭代输出元素: 0,1,2,3,4,5, 0,3,1,4,2,5,
for x in np.nditer(a, order='F'):
Fortran order,即是列序优先;for x in np.nditer(a, order='C'):
C order,即是行序优先; 一行读完再一行
nditer 对象有另一个可选参数 op_flags。 默认情况下,nditer 将视待迭代遍历的数组为只读对象(read-only),为了在遍历数组的同时,实现对数组元素值得修改,必须指定 read-write 或者 write-only 的模式。
import numpy as np a = np.arange(0,60,5) a = a.reshape(3,4) print ('原始数组是:') print (a) print ('\n') for x in np.nditer(a, op_flags=['readwrite']): x[...]=2*x print ('修改后的数组是:') print (a) output: 原始数组是: [[ 0 5 10 15] [20 25 30 35] [40 45 50 55]] 修改后的数组是: [[ 0 10 20 30] [ 40 50 60 70] [ 80 90 100 110]]
- nditer 对象有flags参数,接受以下值:
c_index |
?可以跟踪 C 顺序的索引,一个元素一个元素给出 |
f_index |
?可以跟踪 Fortran 顺序的索引,一个元素一个元素给出 |
multi-index |
?每次迭代可以跟踪一种索引类型 |
external_loop |
给出的值是具有多个值的一维数组,而不是零维数组,一维一维给出 |
- 如果两个数组是可广播的,nditer 组合对象能够同时迭代它们。
上面说了这么多,打基础,下面就来玩转numpy
Numpy 数组操作
Numpy 中包含了一些函数用于处理数组,大概可分为以下几类:
- 修改数组形状
- 翻转数组
- 修改数组维度
- 连接数组
- 分割数组
- 数组元素的添加与删除
修改数组形状
函数 | 描述 |
---|---|
reshape |
不改变数据的条件下修改形状 |
flat |
数组元素迭代器 |
flatten |
返回一份数组拷贝,对拷贝所做的修改不会影响原始数组,展开!! |
ravel |
返回展开数组 |
numpy.reshape(arr, newshape, order='C')
arr
:要修改形状的数组newshape
:整数或者整数数组,新的形状应当兼容原有形状- order:'C' -- 按行,'F' -- 按列,'A' -- 原顺序,'k' -- 元素在内存中的出现顺序。
numpy.ndarray.flat数组元素迭代器
import numpy as np a = np.arange(9).reshape(3,3) print ('原始数组:') for row in a: print (row) #对数组中每个元素都进行处理,可以使用flat属性,该属性是一个数组元素迭代器: print ('迭代后的数组:') for element in a.flat: print (element) output: 原始数组: [0 1 2] [3 4 5] [6 7 8] 迭代后输出: 0 1 2 3 4 5 6 7 8
numpy.ndarray.flatten
ndarray.flatten(order='C')
- order:'C' -- 按行,'F' -- 按列,'A' -- 原顺序,'K' -- 元素在内存中的出现顺序。
numpy.ravel
numpy.ravel() 展平的数组元素,
- 顺序通常是"C风格",
- 返回的是数组视图(view,有点类似 C/C++引用reference的意味),
- 修改会影响原始数组。
翻转数组
函数 | 描述 |
---|---|
transpose |
对换数组的维度 |
ndarray.T |
和 self.transpose() 相同 |
rollaxis |
向后滚动指定的轴 |
swapaxes |
对换数组的两个轴 |
numpy.transpose
numpy.transpose 函数用于对换数组的维度,格式如下:
numpy.transpose(arr, axes) = arr.T
numpy.rollaxis
numpy.rollaxis 函数向后滚动特定的轴到一个特定位置,格式如下:
numpy.rollaxis(arr, axis, start)
arr
:数组axis
:要向后滚动的轴,其它轴的相对位置不会改变start
:默认为零,表示完整的滚动。会滚动到特定位置。
轴
- 对numpy中轴的理解,:
- 使用 a[6] 访问数组 a 中 index 为 6 的元素。从背后实现看,NumPy 会辅助一个轴,轴的取值为 0 到 11。
[ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22]
从概念上看,它的示意图如下所示:

- 对于二维数组b = a.reshape(2,6): 其中a=np.arange(0,24,2)
[[ 0, 2, 4, 6, 8, 10],
[12, 14, 16, 18, 20, 22]]
- shape,(12,) 和 (12,1),其实前者一个轴,后者两个轴,示意图分别如下。

vs
并且,通过上面几幅图看到,无论 shape 如何变化,变化的是视图,底下的 buffer 始终未变。
- 三个轴,变化数组 a 的 shape 为 (2,3,2):
[[[ 0, 2], [ 4, 6], [ 8, 10]], [[12, 14], [16, 18], [20, 22]]]
- 可以升4维吗?
原始的一维数组 a 它一共有 12 个元素,后来,我们变化它为数组 c,shape 为 (2,3,2),那么如何升级为 4 维或任意维呢?
4 维可以为:(1,2,3,2),示意图如下:
轴 i 索引取值只有 0,它被称为自由维度,可以任意插入到原数组的任意轴间。
比如,5 维可以为:(1,2,1,3,2):
import numpy as np # 创建了三维的 ndarray a = np.arange(8).reshape(2,2,2) print ('原数组:') print (a) print ('获取数组中一个值:') print(np.where(a==6)) print(a[1,1,0]) # 为 6 print ('\n') # 将轴 2 滚动到轴 0(宽度到深度) print ('调用 rollaxis 函数:') b = np.rollaxis(a,2,0) # 0-1-2 -》 2-0-1 shape(2,2,2) print (b) # 查看元素 a[1,1,0],即 6 的坐标,变成 [0, 1, 1] # 最后一个 0 移动到最前面 print(np.where(b==6)) print ('\n') # 将轴 2 滚动到轴 1:(宽度到高度) print ('调用 rollaxis 函数:') c = np.rollaxis(a,2,1) print (c) # 查看元素 a[1,1,0],即 6 的坐标,变成 [1, 0, 1] # 最后的 0 和 它前面的 1 对换位置 print(np.where(c==6)) print ('\n') python: 原数组: [[[0 1] [2 3]] [[4 5] [6 7]]] 获取数组中一个值: (array([1]), array([1]), array([0])) 6 调用 rollaxis 函数: [[[0 2] [4 6]] [[1 3] [5 7]]] (array([0]), array([1]), array([1])) 调用 rollaxis 函数: [[[0 2] [1 3]] [[4 6] [5 7]]] (array([1]), array([0]), array([1]))
修改数组维度
维度 | 描述 |
---|---|
broadcast |
产生模仿广播的对象 |
broadcast_to |
将数组广播到新形状,在原始数组上返回只读视图, 它通常不连续 |
expand_dims |
扩展数组的形状 |
squeeze |
从数组的形状中删除一维条目 |
numpy.expand_dims
numpy.expand_dims 函数通过在指定位置插入新的轴来扩展数组形状,函数格式如下:
numpy.expand_dims(arr, axis)
参数说明:
arr
:输入数组axis
:新轴插入的位置
numpy.squeeze
numpy.squeeze 函数从给定数组的形状中删除一维的条目,函数格式如下:
numpy.squeeze(arr, axis)
参数说明:
arr
:输入数组axis
:整数或整数元组,用于选择形状中一维条目的子集

import numpy as np x = np.array(([1,2],[3,4])) print ('数组 x:') print (x) print ('\n') y = np.expand_dims(x, axis = 0) print ('数组 y:') print (y) print ('\n') print ('数组 x 和 y 的形状:') print (x.shape, y.shape) print ('\n') # 在位置 1 插入轴 y = np.expand_dims(x, axis = 1) print ('在位置 1 插入轴之后的数组 y:') print (y) print ('\n') print ('x.ndim 和 y.ndim:') print (x.ndim,y.ndim) print ('\n') print ('x.shape 和 y.shape:') print (x.shape, y.shape) output: 数组 x: [[1 2] [3 4]] 数组 y: [[[1 2] [3 4]]] 数组 x 和 y 的形状: (2, 2) (1, 2, 2) 在位置 1 插入轴之后的数组 y: [[[1 2]] [[3 4]]] x.ndim 和 y.ndim: 2 3 x.shape 和 y.shape: (2, 2) (2, 1, 2)

import numpy as np x = np.arange(9).reshape(3,3,1) print ('数组 x:') print (x) print ('\n') y = np.squeeze(x) print ('数组 y:') print (y) print ('\n') print ('数组 x 和 y 的形状:') print (x.shape, y.shape) output: 数组 x: [[[0] [1] [2]] [[3] [4] [5]] [[6] [7] [8]]] 数组 y: [[0 1 2] [3 4 5] [6 7 8]] 数组 x 和 y 的形状: (3, 3, 1) (3, 3)
连接数组
函数 | 描述 |
---|---|
concatenate |
连接沿现有轴的数组序列 |
stack |
沿着新的轴加入一系列数组。 |
hstack |
水平堆叠序列中的数组(列方向) |
vstack |
竖直堆叠序列中的数组(行方向) |
分割数组
函数 | 数组及操作 |
---|---|
split |
将一个数组分割为多个子数组 |
hsplit |
将一个数组水平分割为多个子数组(按列) |
vsplit |
将一个数组垂直分割为多个子数组(按行) |
数组元素的添加与删除
函数 | 元素及描述 |
---|---|
resize |
返回指定形状的新数组 |
append |
将值添加到数组末尾 |
insert |
沿指定轴将值插入到指定下标之前 |
delete |
删掉某个轴的子数组,并返回删除后的新数组 |
unique |
查找数组内的唯一元素 |
NumPy 位运算
NumPy "bitwise_" 开头的函数是位运算函数。
NumPy 位运算包括以下几个函数:
函数 | 描述 |
---|---|
bitwise_and |
对数组元素执行位与操作 & |
bitwise_or |
对数组元素执行位或操作 ^ |
invert |
按位取反 ~ |
left_shift |
向左移动二进制表示的位 |
right_shift |
向右移动二进制表示的位 |
- 也可以使用 "&"、 "~"、 "|" 和 "^" 等操作符进行计算。
invert
invert() 函数对数组中整数进行位取反运算,即 0 变成 1,1 变成 0。
对于有符号整数,取该二进制数的补码,然后 +1。二进制数,最高位为0表示正数,最高位为 1 表示负数。
看看 ~1 的计算步骤:
- 将
1
(这里叫:原码)转二进制 =00000001
- 按位取反 =
11111110
- 发现符号位(即最高位)为
1
(表示负数),将除符号位之外的其他数字取反 =10000001
- 末位加1取其补码 =
10000010
- 转换回十进制 =
-2
表达式 |
二进制值(2 的补数) | 十进制值 |
---|---|---|
5 | 00000000 00000000 00000000 0000010 | 5 |
~5 | 11111111 11111111 11111111 11111010 | -6 |

import numpy as np print ('13 的位反转,其中 ndarray 的 dtype 是 uint8:') print (np.invert(np.array([13], dtype = np.uint8))) print ('\n') # 比较 13 和 242 的二进制表示,我们发现了位的反转 print ('13 的二进制表示:') print (np.binary_repr(13, width = 8)) print ('\n') print ('242 的二进制表示:') print (np.binary_repr(242, width = 8)) output: 13 的位反转,其中 ndarray 的 dtype 是 uint8: [242] 13 的二进制表示: 00001101 242 的二进制表示: 11110010
- 有符号数在内存中转化为二进制补码进行保存,无符号数直接转化为二进制存储。
有符号数表示方法3种:原码、反码、补码
构成:符号位+数值部分组成
符号位 1 负 0 正
1.原码
正数的 原码 = 反码 = 补码
2.反码
负数:符号位不变,数值位取反(即上面的操作)
3.补码
负数:反码加1得到补码
NumPy 字符串函数
以下函数用于对 dtype 为 numpy.string_ 或 numpy.unicode_ 的数组执行向量化字符串操作。 它们基于 Python 内置库中的标准字符串函数。
这些函数在字符数组类(numpy.char)中定义。
函数 | 描述 |
---|---|
add() |
对两个数组的逐个字符串元素进行连接 |
multiply() | 返回按元素多重连接后的字符串 |
center() |
居中字符串 |
capitalize() |
将字符串第一个字母转换为大写 |
title() |
将字符串的每个单词的第一个字母转换为大写 |
lower() |
数组元素转换为小写 |
upper() |
数组元素转换为大写 |
split() |
指定分隔符对字符串进行分割,并返回数组列表 |
splitlines() |
返回元素中的行列表,以换行符分割 |
strip() |
移除元素开头或者结尾处的特定字符 |
join() |
通过指定分隔符来连接数组中的元素 |
replace() |
使用新字符串替换字符串中的所有子字符串 |
decode() |
数组元素依次调用str.decode |
encode() |
数组元素依次调用str.encode |
NumPy 数学函数
NumPy 提供了标准的三角函数:sin()、cos()、tan()等。
arcsin,arccos,和 arctan 函数返回给定角度的 sin,cos 和 tan 的反三角函数。
这些函数的结果可以通过 numpy.degrees() 函数将弧度转换为角度。
舍入函数
numpy.around() 函数返回指定数字的四舍五入值。
numpy.around(a,decimals)
参数说明:
- a: 数组
- decimals: 舍入的小数位数。 默认值为0。 如果为负,整数将四舍五入到小数点左侧的位置
numpy.floor()向下取整
numpy.floor() 返回小于或者等于指定表达式的最大整数,即向下取整。
numpy.ceil()向上取整
numpy.ceil() 返回大于或者等于指定表达式的最小整数,即向上取整。
NumPy 算术函数
NumPy 算术函数包含简单的加减乘除:

import numpy as np a = np.arange(9, dtype = np.float_).reshape(3,3) print ('第一个数组:') print (a) print ('\n') print ('第二个数组:') b = np.array([10,10,10]) print (b) print ('\n') print ('两个数组相加:') print (np.add(a,b)) print ('\n') print ('两个数组相减:') print (np.subtract(a,b)) print ('\n') print ('两个数组相乘:') print (np.multiply(a,b)) print ('\n') print ('两个数组相除:') print (np.divide(a,b)) output: 第一个数组: [[0. 1. 2.] [3. 4. 5.] [6. 7. 8.]] 第二个数组: [10 10 10] 两个数组相加: [[10. 11. 12.] [13. 14. 15.] [16. 17. 18.]] 两个数组相减: [[-10. -9. -8.] [ -7. -6. -5.] [ -4. -3. -2.]] 两个数组相乘: [[ 0. 10. 20.] [30. 40. 50.] [60. 70. 80.]] 两个数组相除: [[0. 0.1 0.2] [0.3 0.4 0.5] [0.6 0.7 0.8]]
numpy.reciprocal()
numpy.reciprocal() 函数返回参数逐元素的倒数。
需要注意的是数组必须具有相同的形状或符合数组广播规则。
numpy.power()
numpy.power() 函数将第一个输入数组中的元素作为底数,计算它与第二个输入数组中相应元素的幂。
numpy.mod()
numpy.mod() 计算输入数组中相应元素的相除后的余数。 函数 numpy.remainder() 也产生相同的结果。
NumPy 统计函数
NumPy 提供了很多统计函数,用于从数组中查找最小元素,最大元素,百分位标准差和方差等。
- numpy.amin() 用于计算数组中的元素沿指定轴的最小值。
- numpy.amax() 用于计算数组中的元素沿指定轴的最大值。

import numpy as np a = np.array([[3,7,5],[8,4,3],[2,4,9]]) print ('我们的数组是:') print (a) print ('\n') print ('调用 amin() 函数:') print (np.amin(a,1)) print ('\n') print ('再次调用 amin() 函数:') print (np.amin(a,0)) print ('\n') print ('调用 amax() 函数:') print (np.amax(a)) print ('\n') print ('再次调用 amax() 函数:') print (np.amax(a, axis = 0)) output: 我们的数组是: [[3 7 5] [8 4 3] [2 4 9]] 调用 amin() 函数: [3 3 2] 再次调用 amin() 函数: [2 4 3] 调用 amax() 函数: 9 再次调用 amax() 函数: [8 7 9]
numpy.ptp()
numpy.ptp()函数计算数组中元素最大值与最小值的差(最大值 - 最小值)。
numpy.ptp()函数和numpy.amin()一样具有axis参数!
numpy.percentile()
百分位数是统计中使用的度量,表示小于这个值的观察值的百分比。 函数numpy.percentile()接受以下参数。
numpy.percentile(a, q, axis)
参数说明:
- a: 输入数组
- q: 要计算的百分位数,在 0 ~ 100 之间
- axis: 沿着它计算百分位数的轴
numpy.median()
numpy.median() 函数用于计算数组 a 中元素的中位数(中值)
具有axis参数!
numpy.mean()
numpy.mean() 函数返回数组中元素的算术平均值。 如果提供了轴,则沿其计算。
算术平均值是沿轴的元素的总和除以元素的数量。
numpy.average()
numpy.average() 函数根据在另一个数组中给出的各自的权重计算数组中元素的加权平均值。
该函数可以接受一个轴参数。 如果没有指定轴,则数组会被展开。
加权平均值即将各数值乘以相应的权数,然后加总求和得到总体值,再除以总的单位数。

import numpy as np a = np.array([1,2,3,4]) print ('我们的数组是:') print (a) print ('\n') print ('调用 average() 函数:') print (np.average(a)) print ('\n') # 不指定权重时相当于 mean 函数 wts = np.array([4,3,2,1]) print ('再次调用 average() 函数:') print (np.average(a,weights = wts)) print ('\n') # 如果 returned 参数设为 true,则返回权重的和 print ('权重的和:') print (np.average([1,2,3, 4],weights = [4,3,2,1], returned = True)) output: 我们的数组是: [1 2 3 4] 调用 average() 函数: 2.5 再次调用 average() 函数: 2.0 权重的和: (2.0, 10.0)
标准差std
标准差是一组数据平均值分散程度的一种度量。标准差是方差的算术平方根。标准差公式如下:
std = sqrt(mean((x - x.mean())**2))
import numpy as np print (np.std([1,2,3,4]))
方差var
统计中的方差(样本方差)是每个样本值与全体样本值的平均数之差的平方值的平均数,即
mean((x - x.mean())** 2)。
换句话说,标准差是方差的平方根。
import numpy as np print (np.var([1,2,3,4]))
NumPy 排序、条件刷选函数
看原出处:-> 😑 <-
NumPy 矩阵库(Matrix)
https://www.runoob.com/numpy/numpy-matrix.html
NumPy 线性代数
https://www.runoob.com/numpy/numpy-linear-algebra.html
NumPy 提供了线性代数函数库 linalg,该库包含了线性代数所需的所有功能,可以看看下面的说明:
函数 | 描述 |
---|---|
dot |
两个数组的点积,即元素对应相乘。 |
vdot |
两个向量的点积 |
inner |
两个数组的内积 |
matmul |
两个数组的矩阵积 |
determinant |
数组的行列式 |
solve |
求解线性矩阵方程 |
inv |
计算矩阵的乘法逆矩阵 |
先这样了,用到再看再学是🥱
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
2020-08-12 simpSubCipher and simpleSubHacker