You are on page 1of 10

第二次课(Numpy)

1.Numpy简介

NumPy 是在 Python 中进行科学计算经常用到的基本包,主要用于对多维数组执行计算,有着广泛的应用场景,例如:

机器学习: 在机器学习中,经常需要进行各种矩阵运算,NumPy 提供了编写简单、运行快速的运算接口。此外,NumPy 数


组也被用于存储训练数据和模型的参数。
图像处理: 计算机中的图像被表示为多维数组。
数学任务: 替代 MatLab 执行例如数值积分、微分、内插、外推等数学任务。
要使用 NumPy,需要首先导入 numpy 库
import numpy as np (一般都简写作np)

ndarray:

ndarray 是 NumPy 中的基本对象,它是一个由相同类型的元素组成的多维数组,通过非负整数元组进行索引(这说明列表操作


中负数代表的倒数不再可行)。在 NumPy,每个维度被称为轴 ( axis ) 。下面我们将围绕 ndarray 的基本操作展开本次课。

2.数组的创建:

详细文档请参见 Array creation routines。

2.1 从Python的序列容器创建数组

可以直接使用 np.array 从Python的list或tuple创建数组

arr_1d = np.array((1, 2, 3)) # 元组变ndarray [1 2 3]


arr_2d = np.array([[1, 2, 3], [4, 5, 6]]) # 多维列表变ndarray [[1 2 3] [4 5 6]]

数组有以下常用属性:

维度: arr_2d.ndim # 2
形状: arr_2d.shape # (2,3) 是各维度拥有元素个数组成的元组
元素总数: arr_2d.size # 6
元素数据类型: arr_2d.dtype # int32

2.2使用numpy预置的函数创建数组

前注:
NumPy 创建数组的函数一般还可接受名为 dtype 的参数,用于指定元素的数据类型。可选的类型可以参见此链接。例如:

print(np.zeros((1,), dtype=int)) # [0]


print(np.zeros((1,), dtype=np.float32)) # [0.]
np.arrange(1,3,dtype=float) # [1. 2.]

2.2.1 一维数组创建函数

arange(start=0, stop, step=1) : 类似于 python 中的 range ,创建以 start 起(含)至 stop (不含),步长为 step
(可以为负,代表从后向前列) 的数组。最后的参数dtype若不指定,由系统自动推断
NOTICE:注意是 arange 不是 arrange (这个函数名经常搞错)
linspace(start, stop, num=50, endpoint=True) : 创建从 start 开始(含)至 stop (是否包含取决于 endpoint ),由
num 个均匀散布(线性空间中均匀分布)的元素组成的数组。
logspace(start, stop, num=50, endpoint=True, base=10.0) : 创建从 base ** start 开始(含)至 base ** stop 结束
(是否包含取决于 endpoint ),由 num 个在对数尺度上均匀散布的元素组成的数组。(也就是对num线性)

print(np.arange(3)) # [0 1 2]
print(np.arange(1, 7, 2)) # [1 3 5]
print(np.arange(10, 0, -2)) # [10 8 6 4 2]
print(np.linspace(0, 50, 5, endpoint=True)) # [ 0. 12.5 25. 37.5 50. ]
print(np.logspace(0, 3, 4)) # [ 1. 10. 100. 1000.]

2.2.2 二维数组创建函数

常用的二维数组创建函数包括:

eye(N, M=None) : 创建 N × M 的单位矩阵(可以不是方阵)。(没有M就是一个列向量,即一维数组)


diag(v) : 创建以 v 为对角线元素的对角矩阵。v是一个列表或元组

np.eye(3,4) # array([ [1., 0., 0., 0.] , [0., 1., 0., 0.] , [0., 0., 1., 0.] ])
print(np.diag([1,2,3])) # [[1 0 0] [0 2 0] [0 0 3]]
print( np.diag( (1,2,3) ) ) # [[1 0 0] [0 2 0] [0 0 3]]
print( np.diag( range(1,3) ) ) # [[1 0] [0 2]]

2.2.3通用数组创建函数

该类函数在创建数组时,通常需要指定数组的形状,或者给定一个参考数组。常见的通用数组创建函数包括:

zeros(shape) : 创建一个形状为 shape 的零矩阵。(传进去的shape可以是元组或列表)


zeros_like(arr) : 创建一个形状与 arr 相同的零矩阵。
ones(shape) : 创建一个形状为 shape 的全 1 矩阵。
ones_like(arr) : 创建一个形状与 arr 相同的全 1 矩阵。
random.random(shape) : 创建一个形状为 shape ,元素在 [0, 1) 随机取值的矩阵。

arr_zero = np.zeros((2, 3)) # 或者是[2,3],效果是一样的


arr_zero # array([[0., 0., 0.], [0., 0., 0.]])

np.ones_like(arr_zero) # array([[1., 1., 1.], [1., 1., 1.]])


np.random.random((2, 2)) # array([[0.41917339, 0.87159905], [0.09929726, 0.82764991]])

PS:注意到直接把数组写出来元素之间带逗号,前面还有格式 array
但用print打印出来就没有逗号

3.数组的索引

详细文档请参见 Indexing on ndarrays。

3.1切片

我们可以采用类似 python 中的 list 的方式对 ndarray 数组进行切片。但不同的是,ndarray 可以以逗号分隔,一次性指定每个维


度的切片方式。

PS:可以使用reshape()函数改变数组形状
arr = np.arange(11, 36).reshape((5, 5))
print(arr[0, 1:4]) # 注意维度变化,原来的第 0 维被压缩了
print(arr[1:4, 0]) # 注意维度变化,原来的第 1 维被压缩了
print(arr[::2, ::2]) # 指定步长
print(arr[:, 1]) # 第 0 维全选
'''
第一个切片`a[ 0 , 1:4 ]`是只对第一行切片(第一个参数指行数),`1:4`是从第二个到第五个(不含第五个)
第二个切片和第一个正好相反
第三个切片`a[ : : 2 , : : 2 ]`是对列和行都进行从头到尾(含尾)步长为2的切片
第四个`a[ : , 1 ]`是只取第一列,行数全取
'''

注意!通过切片选择返回的数组是原始数组的一个视图 (view),并未发生数据的拷贝。在视图上做的修改都会反馈到原始数组
上。比如:

arr = np.arange(1, 7).reshape((2, 3))


print(arr) # [[1 2 3] [4 5 6]]
view = arr[:, 1]
print(view) # [2 5]
view[0] = 9
print(arr) # [[1 _9_ 3] [4 5 6]]
上面是对切片得到的view的改变,但因为是视图,一切改变还会反馈到原始数组上

用 ndarray.copy或copy 完成对数组数据的深拷贝

# arr还是[[1 9 3] [4 5 6]]
view = arr[:, 1].copy()
view[0] = 7
print(arr) # [[1 9 3] [4 5 6]] view的改变对arr没有任何影响

3.2 整数数组索引

我们可以使用整数数组进行索引。通过为每一个维度提供一个坐标数组,可以选取任意位置的元素。此时返回的数组不再是一个
view 了。(相当于经过了一次copy)

arr = np.arange(1, 7).reshape((2, 3))

copy_arr = arr[[0, 1, 0], [0, 1, 2]]


print(copy_arr) # [1 5 3] 取了arr的(0,0)、(1,1)、(0,2)元构成一个3维的数组
copy_arr[0] = 9
print(arr) # [[1 2 3] [4 5 6]] copy_arr的改变对arr没有影响
------------------
上面的copy_arr定义方式和arr_copy = np.array( [ arr[0, 0], arr[1, 1], arr[0, 2] ] )是等价的
上面把各维的坐标分别作为一个列表输入,因此不同列表之间维数一定要相等,维数代表了输出有多少个元素

3.3布尔数组索引

我们可以使用一个与原数组形状匹配的布尔数组来选择元素(此时返回的数组同样不再是一个 view 了)。例如:


mask = (arr % 2 == 0) # 选择偶数
print(mask) # [[False True False] [ True False True]]
print(arr[mask]) # [2 4 6]
True代表对应的元素被选择,False表示对应元素未被选择,所以需要和原数组形状相匹配的布尔数组

4.数组的运算

4.1算数运算

NumPy 中 ndarray 数组的基本运算(加、减、乘、除、整除、求余、幂等)都是逐元素 (element-wise) 的(例如这里的乘法并


不是矩阵乘法)。其指定方式既可以采用 + , - , * , / , // , % , ** 等运算符,也可以使用 NumPy 函数。

x = np.array([[1,2],[3,4]], dtype=np.float32)
y = np.array([[5,6],[7,8]], dtype=np.float32)

print(x + y) # np.add(x, y)
# [[ 6. 8.] [10. 12.]]
print(x * y) # np.multiply(x, y)
# [[ 5. 12.] [21. 32.]]
print(x / y) # np.divide(x, y)
# [[0.2 0.33333334]
[0.42857143 0.5 ]] (写成两行的形式更容易分辨)
print(x ** 2) # np.power(x, 2)
# [[ 1. 4.] [ 9. 16.]]

补充:BroadCasting(广播机制)

详细内容请参见 Broadcasting (中文版)


在 NumPy 的数组运算中,通常要求参与运算的两个数组的形状相同,但在满足某些要求的情况下,NumPy 可以自动地将较小的
数组进行复制,使得其与较大的数组形状相同。举例如下:

a = np.array([1.0, 2.0, 3.0])


b = 2.0
print(a * b) # 标量广播为数组 [2. 4. 6.] (b被广播成[2. 2. 2.])

x = np.arange(8).reshape((2, 2, 2))
y = np.array([[10, 20], [30, 40]])
print(x)
print(x + y) # 小数组广播为大数组(2*2*2的数组)
# x= [ [[0 1] [2 3]]
[[4 5] [6 7]] ]
x+y = [ [[10 21] [32 43]]
[[14 25] [36 47]] ]

m = np.random.randn(8, 1, 6, 1)
n = np.random.randn(7, 1, 5)
print(m.shape)
print(n.shape)
print((m + n).shape) # 一般广播规则:维度从后往前匹配,维度兼容的条件:相等或其中1个是1
# (8, 1, 6, 1) (7, 1, 5) (8, 7, 6, 5) # (7,1,5)也可看成(7,1,5,1)

k = np.random.randn(8, 1, 6, 6)
l = np.random.randn(7, 1, 5)
print((k+l).shape) # 不满足一般广播规则,在最后一维失配,会报错
一般广播规则:维度从后往前匹配,维度兼容的条件:相等或其中1个是1(只有是1才能复制扩充,否则就不知道应该怎么扩充,
因此会报错)

4.2常用数学函数

NumPy 中预置了很多数学函数,大家可以自己探索用法。完整的数学函数列表见 Mathematical functions 和 Statistics。

4.2.1 单点运算

NumPy 中预置了例如求绝对值、(反)三角函数、(反)双曲函数、指数、对数、取整、截断等常用函数,这些函数也都是逐元
素运算的。下面是一些示例:

angle = np.array([0, np.pi / 4, np.pi / 2, np.pi * 3 / 4])


print(np.sin(angle)) # [0. 0.70710678 1. 0.70710678]
# 对angle这个列表各个元素使用sin函数并返回由结果组成的列表

power = np.array([0, 1, 2, 3])


result = np.exp(power)
print(result) # [ 1. 2.71828183 7.3890561 20.08553692]
print(np.log(result)) # [0. 1. 2. 3.] (log是自然对数)

4.2.2 统计量

NumPy 中预置了求平均值、中位数、方差、标准差,求和、求积,求最大、最小值的函数,很多函数可以通过 axis 参数指定沿


某一个轴求值(不指定就是对所有元素),还可指定通过 keepdims 参数指定求值操作是否要保留原数组的形状。一些常用的函
数如下:

sum : 求和。
prod : 求积。
mean : 求均值。
std : 求标准差。
var : 求方差。
amax : 求最大值。也可以通过 max 调用。
amin : 求最小值。也可以通过 min 调用。
例如:

arr = np.random.random((2, 2))


print(arr) # [[0.15452196 0.6329802 ] [0.52389797 0.14241565]](比如某一次结果是这个)
print(np.mean(arr)) # 或 `arr.mean()`。求所有元素的平均值。 0.36345394601499525
print(arr.mean(axis=0)) # 或 `np.mean(arr, axis=0)`。对第 0 维求平均值。即对每一列求均值
# [0.33920997 0.38769793]
print(np.min(arr)) # 或 `arr.min()`, `np.amin(arr)`。求所有元素的最小值。
# 0.14241565157733171
print(arr.max(axis=1, keepdims=True)) # 对第 1 维求最大值,保留维度。
# [[0.6329802 ] [0.52389797]] # 保持维度:保持第0维的维度,也就是结果第0维仍然是2
# 否则结果应该是[0.6329802 0.52389797] (第0维变为1,第1维是2)

注意此处不要和 maximum , minimum 两个函数混淆。这两个函数是对于2个数组,返回逐元素求最大/小值的结果。是两个数


组比较,返回一个新数组,每个元素是对应位置两个数组元素的最大值

print(np.maximum([2, 3, 4], [1, 5, 2])) #[2 5 4]


print(np.maximum(np.eye(2), [0.5, 2])) # [[1. 2. ] [0.5 2. ]]

4.3 向量、矩阵运算
前面提到,数组的 * 运算为逐元素相乘,并不是矩阵乘法。对于矩阵乘法,应当使用 @ 运算符,或者 matmul 函数。当两
个数组都是二维时,也可以使用 dot 。

x = np.array([[1,2],[3,4]], dtype=np.float32)
y = np.array([[5,6],[7,8]], dtype=np.float32)
x @ y # equivalent to `np.matmul(x, y)`
# array([[19., 22.], [43., 50.]], dtype=float32)

使用 inner(x, y) 或 dot(x, y) 或 x.dot(y) 进行向量点乘。


使用 cross(x, y) 进行向量叉乘。

x = np.array([1, 2, 3])
y = np.array([4, 5, 6])
print(np.cross(x,y)) # [-3 6 -3]

使用 linalg.norm(x[, ord, axis, keepdims=False]) 求向量或矩阵的范数。(中括号里面是可以不给的参数,ord是指求哪种


范数,默认是2范数)

x = np.array([1, 1])
print(np.linalg.norm(x)) # 求向量 x 的2范数 1.4142135623730951
y = np.array([[1, 2], [3, 4]])
print(np.linalg.norm(y, axis=1)) # 求 y 的每一行的2范数

使用 linalg.inv 求矩阵的逆。

x = np.array([[1,2],[3,4]], dtype=np.float32)
y = np.linalg.inv(x)
print(y) # [[-2. 1. ] [ 1.5 -0.5]]
print(np.matmul(x, y)) # [[1. 0.] [0. 1.]] 验证确实是逆矩阵

4.4排序和查找

更详细的内容,请参考 Sorting, searching, and counting。

4.4.1 排序

排序常用的函数是:

sort(a, axis=-1) : 沿着给定的 axis 从小到大排序元素。如果 axis 为 None ,则会先把数组展平为一维,然后再对所有


元素进行排序。该函数返回的是一个新数组,而如果使用 ndarray.sort ,则会在原地进行排序,不返回值。(axis=-1指对
最后一维进行排序)ndarray.sort是定义好的数组(比如x)的成员函数,因此是原地操作,对原数组直接有影响,而np.sort
函数返回了一个新数组,对原数组无影响
argsort(a, axis=-1) : 按照与 sort 相同的规则(从小到大)排序元素,返回排序后的元素在原数组的排序维度上的索引。
这时相当于先把原数组展开成一个一维数组,然后对其进行排序

x = np.array([[0, 3], [4, 2]])


y = x.copy()
print("排序前x的值\n",x) # 排序前x的值 [[0 3] [4 2]]
print("x沿最后一维排序\n", np.sort(x)) # 沿最后一维进行排序 x沿最后一维排序 [[0 3] [2 4]]
print("排序后x的值\n",x) # np.sort返回新数组,对原本x无影响 排序后x的值 [[0 3] [4 2]]
y.sort() # 沿最后一位进行排序,对原本y有影响
print("y沿最后一位排序\n",y) # y沿最后一维排序 [[0 3] [2 4]]
print(np.sort(x, axis=0)) # 沿第 0 维进行排序 [[0 2] [4 3]]
print(np.sort(x, axis=None)) # 对所有元素进行排序 [0 2 3 4]

z =np.array([[1,2,3],[0,1,2]])
print(np.argsort(z)) # [[0 1 2] [0 1 2]]
# 第一个[0 1 2]表示第一行就是按从小到大排列的,因为没有指定axis,默认是从最后一维(在这里是第1维,也就是行)第二个同理
print(np.argsort(z, axis=0)) # [[1 1 1] [0 0 0]]
# 对列排列,结果也要从列来看,每一列都是[1 0]说明每一列都是从大到小排列,所以需要反过来排列

如何根据 argsort 返回的索引从原数组提取元素呢?需要用到 take_along_axis(arr, indices, axis) 。

x = [[0 3] [4 2]]
print(np.take_along_axis(x, np.argsort(x, axis=0), axis=0)) # [[0 2] [4 3]]

NOTICE:
如果axis=None,会对所有元素进行排序
print(np.argsort(x,axis=None)) # [0 3 1 2]
我们发现,对所有元素进行排序返回的索引是一个一维数组,这是因为原数组在排序时被展平为了一个一维数组。那么如何根据这
个索引得到元素在原数组中的多维的索引呢?这里需要用到 unravel_index(indices, shape) 函数。输入一维索引数组和原数组
的形状,该函数会将一维索引转换为多维索引。(返回多个一维数组,代表了原数组各个维度上的索引)

print(np.unravel_index(np.argsort(x, axis=None), x.shape))


# ( array([0, 1, 0, 1], dtype=int64), array([0, 1, 1, 0], dtype=int64) )
可以看到,函数返回了两个一维数组,分别对应原数组两个维度上的索引。
一维数组的维数是原数组元素的个数(比如这里是4)两个一维数组合成是各个原数组元素的位置坐标
一维数组的数量是原数组的维度

4.4.2 查找

常用的查找函数包括:

argmax(a, axis=None) : 沿 axis 轴找出取值最大的元素的索引。若不指定 axis ,则会先将数组展平到一维,然后再进行


查找。
[`argmin(a, axis=None]) ](https://numpy.org/doc/stable/reference/generated/numpy.argmin.html): 沿 axis 轴找出取值最
小的元素的索引。若不指定 axis ,则会先将数组展平到一维,然后再进行查找。 与 argsort 一样,这里有时也会用到 unravel_index
和 take_along_axis`。

x = np.array([[0, 5, 3], [4, 6, 2]])


print(np.argmin(x, axis=0)) # [0 0 1] 返回每列
print(np.argmax(x)) #先摊平数组再找最大值的索引 4
print(x[ a,range( x.shape(1) ) ]) # 两个三维数组给出了x每列最小值的坐标,和argsort返回值相似

argwhere(a) : 返回数组中非零元素的索引构成的数组。数组的形状为 (N, a.ndim) , N 为查找到元素的个数。注: True


也是非零元素(False是0元素),因此我们可以传入通过条件比较得到的布尔数组来筛选出满足条件的元素。(数组作为参数的
布尔表达式会返回布尔数组)
nonzero(a) : 对数组中的非零元素,分别返回每一维的索引构成的数组。因为 argwhere 返回的索引数组不适合用于从原数
组提取元素,所以有时会用 nonzero 替代。

x = [[0, 5, 3], [4, 5, 2]]


print(np.argwhere(x > 3)) # [[0 1] [1 0] [1 1]]
ind_0, ind_1 = np.nonzero(x > 3)
print(ind_0, ind_1) # [0 1 1] [1 0 1]
print(x[ind_0, ind_1]) # [5,4,6]
print(x[x > 3]) # 其实用布尔数组索引就行了 [5,4,6]
PS: x > 3这一部分使用到了广播机制以及利用布尔表达式生成布尔数组,3这个标量被广播为

5.数组的操作

详细文档请参见 Array manipulation routines。

5.1 改变数组形状:

指定变化:

reshape(a, shape) / ndarray.reshape(shape) : 改变数组的形状为 shape 。 shape 里的某一维的大小可以设置为 -1 ,


此时将根据数组元素个数和其他维度大小自动推断该维度的大小。shape是一个元组
展平:
ravel(a) / ndarray.ravel() : 将数组展平为一维。返回的是原数组的 view。
ndarray.flatten() : 将数组展平为一维。返回的是新的数组。
删除:
squeeze(a, axis=None) / ndarray.squeeze(axis=None) : 删除数组中大小为 1 的维度。如果指定了 axis ,就只删除该
维度。
插入:
expand_dims(a, axis) : 向 axis 处插入一个维度。(即axis处是一个新维度,原有维度全部向后移动一维)

x = np.array([[1], [2]])
print(x, x.shape) # [[1] [2]] (2, 1)
y = x.squeeze(1)
print(y, y.shape) # [1 2] (2,)
z = np.expand_dims(x, axis=0)
print(z, z.shape) # [[[1] [2]]] (1, 2, 1) (2,1) --> (1,2,1) 前面增加了一维

还可以利用特殊的索引值 np.newaxis (也可以写 None ) 来扩展维度。例如:

print(y, y.shape) # [1 2] (2,)


print(y[np.newaxis], y[np.newaxis].shape) # 扩展第0维 [ [1 2] ] (1, 2)
print(y[:,np.newaxis],y[:,np.newaxis].shape) # 扩展第1维 [ [1] [2] ] (2, 1) `:`表示对应维数
# 比如 [ : , np.newaxis] 就表示在最后增加一维(因为y本身只有一维,前面只需要加一个 :)
# 如果y有更多维,就需要更多的: 通过:来精准定位newaxis添加的位置
print(y[..., np.newaxis], y[..., np.newaxis].shape) # 扩展最后一维。`...` 表示之前的所有维度。
# [ [1] [2] ] (2, 1)

NOTICE:添加的新维度的值都是1

5.2转置

transpose(a, axes=None) / ndarray.transpose(axes=None) : 按照 axes 指定的维度顺序转置数组。若未指定 axes ,


则反转所有维度的顺序。
ndarray.T : 等同于 ndarray.transpose() 。
上面都会返回一个新数组,对原数组没有影响

x = np.array([[1, 2], [3, 4], [5, 6]])


print(np.transpose(x)) # [[1 3 5] [2 4 6]]
print(x.T) # [[1 3 5] [2 4 6]]

x = np.arange(6).reshape((1, 2, 3))
print(x, x.shape) # [[[0 1 2] [3 4 5]]] (1, 2, 3)
y = x.transpose((1, 2, 0)) # (0,1,2)是原本正常的维度顺序,1,2,0就是维度全部前移一位
print(y, y.shape) # [[[0] [1] [2]] [[3] [4] [5]]] (2, 3, 1)
5.3改变数据类型

ndarray.astype(dtype) : 复制并转换数组到指定的数据类型。

img = np.random.random((2, 2)) # 像素值取值 0~1 的图像


print(img) # [[0.91401126 0.42424438] [0.02389619 0.41669336]]
img = (img * 255).round().astype(np.uint8) # 转换为常见的 uint8 图像 round()对数组中的数取四舍五入
print(img) # [[233 108] [ 6 106]]

5.4 数组的拼接与堆叠

concatenate(arrays, axis=0) : 在已有的维度上,拼接多个数组。若 axis 为 None ,则会先将所有待拼接数组转换为一维


数组,再进行拼接。
stack(arrays, axis=0) : 沿着新的维度堆叠多个数组。相当于先都拓展出指定维度,然后各个数组沿着这个维度进行拼接
能够沿着某维度拼接要求其他维度一定要完全相同,能沿着指定新维度堆叠要求所有维度都对应相同

img_a = np.array([[1, 2], [3, 4]])


img_b = np.array([[5, 6], [7, 8]])
print(np.concatenate([img_a, img_b], axis=0)) # [[1 2] [3 4] [5 6] [7 8]]
print(np.concatenate([img_a, img_b], axis=1)) # [[1 2 5 6] [3 4 7 8]]

img_stack_channel = np.stack([img_a, img_b], axis=2)


print(img_stack_channel, img_stack_channel.shape) # [[[1 5] [2 6]] [[3 7] [4 8]]] (2, 2, 2)
img_stack_batch = np.stack([img_a, img_b], axis=0)
print(img_stack_batch, img_stack_batch.shape) # [[[1 2] [3 4]] [[5 6] [7 8]]] (2, 2, 2)

tile(arr, reps) : 将 arr 按照 reps 指定的维度和次数进行堆叠。(自己堆叠)

arr = np.array([0, 1, 2])


print(np.tile(arr, 2)) # [0 1 2 0 1 2] 只有一个参数默认是
print(np.tile(arr, (2, 2))) # [[0 1 2 0 1 2] [0 1 2 0 1 2]]

6. 数组的文件I/O

完整文档请参见 Input and output。

有时,我们需要将某个数组保存到文件,或是从文件中读取数组。通常使用如下函数:

load(file) : 从 .npy 或 .npz 文件读取数组。


save(file, arr) : 保存单个数组到 .npy 文件。(如果文件不存在就会创建文件)
savez(file, key0=arr0[, key1=arr1]) : 保存多个数组到 .npz 文件。
savez_compressed(file, key0=arr0[, key1=arr1]) : 同 savez ,但会进行压缩处理。
示例如下:

x = np.random.random((2, 2))
print(x)
np.save('x.npy', x)

x_loaded = np.load('x.npy')
print(x_loaded)

y = np.random.random((2, 2))
print(y)
np.savez('arrays.npz', x=x, y=y)
# x=x 的意思是将数组 x 保存为关键字 'x' 。
data = np.load('arrays.npz')
x_loaded, y_loaded = data['x'], data['y'] # 使用'x'作为关键词参数引用data中的x数组
print(x_loaded)
print(y_loaded)
# 综上,`x=x` 在 `np.savez` 函数调用中指定了保存数组时的关键字,而在加载 `.npz` 文件时使用 `'x'`(作为字符串)来引用这个关键字
并检索相应的数组。

You might also like