NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。
NumPy 是一个运行速度非常快的数学库,主要用于数组计算,包含:
NumPy 通常与 SciPy(Scientific Python)和 Matplotlib(绘图库)一起使用, 这种组合广泛用于替代 MatLab,是一个强大的科学计算环境,有助于我们通过 Python 学习数据科学或者机器学习。
NumPy 最重要的一个特点是其 N 维数组对象 ndarray,它是一系列同类型数据的集合,以 0 下标为开始进行集合中元素的索引。
ndarray 对象是用于存放同类型元素的多维数组
ndarray 中的每个元素在内存中都有相同存储大小的区域
ndarray 内部由以下内容组成:
一个指向数据(内存或内存映射文件中的一块数据)的指针。
数据类型,描述在数组中的固定大小值的格子。
一个表示数组形状(shape)的元组,表示各维度大小的元组。
一个跨度元组(stride),其中的整数指的是为了前进到当前维度下一个元素需要"跨过"的字节数。跨度可以是负数,这样会使数组在内存中后向移动
ndarray 的内部结构:
创建一个 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 | 指定生成数组的最小维度 |
import numpy as np
a = np.array([1,2,3])
print (a)
# [1, 2, 3]
# 多于一个维度
import numpy as np
a = np.array([[1, 2], [3, 4]])
print (a)
# [[1, 2]
# [3, 4]]
# 最小维度
import numpy as np
a = np.array([1, 2, 3,4,5], ndmin = 2)
print (a)
# [[1, 2, 3, 4, 5]]
# dtype 参数
import numpy as np
a = np.array([1, 2, 3], dtype = complex)
print (a)
# [ 1.+0.j, 2.+0.j, 3.+0.j]
numpy 的数值类型实际上是 dtype 对象的实例,并对应唯一的字符,包括 np.bool_,np.int32,np.float32,等等。
数据类型对象是用来描述与数组对应的内存区域如何使用,这依赖如下几个方面:
NumPy 数组的一些基本属性:
NumPy 数组的维数称为秩(rank),一维数组的秩为 1,二维数组的秩为 2,以此类推。
在 NumPy中,每一个线性的数组称为是一个轴(axis),也就是维度(dimensions)。比如说,二维数组相当于是两个一维数组,其中第一个一维数组中每个元素又是一个一维数组。所以一维数组就是 NumPy 中的轴(axis),第一个轴相当于是底层数组,第二个轴是底层数组里的数组。而轴的数量——秩,就是数组的维数。可通过axis进行声明。
NumPy 的数组中比较重要 ndarray 对象属性有:
属性 | 说明 |
---|---|
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 | 包含实际数组元素的缓冲区,由于一般通过数组的索引获取元素,所以通常不需要使用这个属性 |
a = np.arange(24)
print (a.ndim) # a 现只有一个维度
# 1
# 现在调整其大小
b = a.reshape(2,4,3) # b 现在拥有三个维度
print (b.ndim)
# 3
a = np.array([[1,2,3],[4,5,6]])
print (a.shape)
# (2,3)
a = np.array([[1,2,3],[4,5,6]])
b = a.reshape(3,2)
print (b)
# [[1, 2]
# [3, 4]
# [5, 6]]
ndarray 数组除了可以使用底层 ndarray 构造器来创建外,也可以通过以下几种方式来创建:
属性 | 说明 |
---|---|
numpy.empty(shape, dtype = float, order = ‘C’) | 创建一个指定形状(shape)、数据类型(dtype)且未初始化的数组(元素为随机值) |
numpy.zeros(shape, dtype = float, order = ‘C’) | 创建指定大小的数组,数组元素以 0 来填充 |
numpy.ones(shape, dtype = None, order = ‘C’) | 创建指定形状的数组,数组元素以 1 来填充 |
属性 | 说明 |
---|---|
numpy.asarray(a, dtype = None, order = None) | 已有的“数组”a可以是列表, 列表的元组, 元组, 元组的元组, 元组的列表,多维数组 |
numpy.fromiter(iterable, dtype, count=-1) | 从可迭代对象(如生成器)中建立 ndarray 对象,返回一维数组 |
x = [1,2,3]
a = np.asarray(x, dtype = float)
print (a)
# [ 1. 2. 3.]
# 使用 range 函数创建列表对象
list=range(5)
it=iter(list)
# 使用迭代器创建 ndarray
x=np.fromiter(it, dtype=float)
print(x)
属性 | 说明 |
---|---|
numpy.arange(start, stop, step, dtype) | 根据 start 与 stop 指定的范围以及 step 设定的步长,生成一个 ndarray |
np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None) | 用于创建一个一维数组,数组是一个等差数列构成 |
np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None) | 创建一个于等比数列 |
x = np.arange(10,20,2)
print (x)
# [10 12 14 16 18]
a = np.linspace(1,10,10)
print(a)
# [ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]
a = np.logspace(0,9,10,base=2)
print (a)
# [ 1. 2. 4. 8. 16. 32. 64. 128. 256. 512.]
ndarray对象的内容可以通过索引或切片来访问和修改,与 Python 中 list 的切片操作一样。
ndarray 数组可以基于 0 - n 的下标进行索引,切片对象可以通过内置的 slice 函数,并设置 start, stop 及 step 参数进行,从原数组中切割出一个新数组。
a = np.arange(10)
s = slice(2,7,2) # 从索引 2 开始到索引 7 停止,间隔为2
print (a[s])
# [2 4 6]
通过冒号分隔切片参数 start:stop:step 来进行切片操作:
a = np.arange(10)
b = a[2:7:2] # 从索引 2 开始到索引 7 停止,间隔为 2
print(b)
冒号 : 的解释:如果只放置一个参数,如 [2],将返回与该索引相对应的单个元素。如果为 [2:],表示从该索引开始以后的所有项都将被提取。如果使用了两个参数,如 [2:7],那么则提取两个索引(不包括停止索引)之间的项。
多维数组同样适用上述索引提取方法:
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print(a)
# [[1 2 3]
# [3 4 5]
# [4 5 6]]
# 从某个索引处开始切割
print('从数组索引 a[1:] 处开始切割')
print(a[1:])
# [[3 4 5]
# [4 5 6]]
切片还可以包括省略号 …,来使选择元组的长度与数组的维度相同。 如果在行位置使用省略号,它将返回包含行中元素的 ndarray。
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print (a[...,1]) # 第2列元素
# [2 4 5]
NumPy 比一般的 Python 序列提供更多的索引方式。除了之前看到的用整数和切片的索引外,数组可以由整数数组索引、布尔索引及花式索引。
整数索引
x = np.array([[1, 2], [3, 4], [5, 6]])
y = x[[0,1,2], [0,1,0]]
print (y)
# [1 4 5]
布尔索引
可以通过一个布尔数组来索引目标数组。
布尔索引通过布尔运算(如:比较运算符)来获取符合指定条件的元素的数组。
# 获取大于 5 的元素
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
print (x[x > 5])
# [ 6 7 8 9 10 11]
# 从数组中过滤掉缺失元素
a = np.array([np.nan, 1,2,np.nan,3,4,5])
print (a[~np.isnan(a)])
花式索引
花式索引指的是利用整数数组进行索引。
花式索引根据索引数组的值作为目标数组的某个轴的下标来取值。对于使用一维整型数组作为索引,如果目标是一维数组,那么索引的结果就是对应位置的元素;如果目标是二维数组,那么就是对应下标的行。
花式索引跟切片不一样,它总是将数据复制到新数组中。
x=np.arange(32).reshape((8,4))
print (x[[4,2,1,7]])
# [[16 17 18 19]
# [ 8 9 10 11]
# [ 4 5 6 7]
# [28 29 30 31]]
x=np.arange(32).reshape((8,4))
print (x[np.ix_([1,5,7,2],[0,3,1,2])])
# [[ 4 7 5 6]
# [20 23 21 22]
# [28 31 29 30]
# [ 8 11 9 10]]
广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式, 对数组的算术运算通常在相应的元素上进行。
如果两个数组 a 和 b 形状相同,即满足 a.shape == b.shape,那么 a*b 的结果就是 a 与 b 数组对应位相乘。这要求维数相同,且各维度的长度相同。
当运算中的 2 个数组的形状不同时,numpy 将自动触发广播机制。如:
a = np.array([[ 0, 0, 0],
[10,10,10],
[20,20,20],
[30,30,30]])
b = np.array([1,2,3])
print(a + b)
# [[ 1 2 3]
# [11 12 13]
# [21 22 23]
# [31 32 33]]
NumPy 迭代器对象 numpy.nditer 提供了一种灵活访问一个或者多个数组元素的方式。
迭代器最基本的任务的可以完成对数组元素的访问。
# 使用 arange() 函数创建一个 2X3 数组,并使用 nditer 对它进行迭代
a = np.arange(6).reshape(2,3)
for x in np.nditer(a):
print (x, end=", " )
# 0, 1, 2, 3, 4, 5,
以上实例不是使用标准 C 或者 Fortran 顺序,选择的顺序是和数组内存布局一致的,这样做是为了提升访问的效率,默认是行序优先(row-major order,或者说是 C-order)
Numpy 中包含了一些函数用于处理数组,大概可分为以下几类:
函数 | 描述 | 备注 |
---|---|---|
numpy.reshape(arr, newshape, order=‘C’) | 不改变数据的条件下修改形状 | |
numpy.ndarray.flat | 对数组中每个元素都进行处理,可以使用flat属性,该属性是一个数组元素迭代器 | |
ndarray.flatten(order=‘C’) | 返回一份数组拷贝,对拷贝所做的修改不会影响原始数组 | |
numpy.ravel(a, order=‘C’) | 展平的数组元素,顺序通常是"C风格",返回的是数组视图(view,有点类似 C/C++引用reference的意味),修改会影响原始数组 | 返回一维ndarray |
a = np.arange(8).reshape(2,4)
print (a)
# [0 1 2 3 4 5 6 7]
print (a.ravel())
# [0 4 1 5 2 6 3 7]
函数 | 描述 | 备注 |
---|---|---|
numpy.transpose(arr, axes) | 对换数组的维度 | axes:整数列表,对应维度,通常所有维度都会对换,numpy.ndarray.T 类似 numpy.transpose |
numpy.rollaxis(arr, axis, start) | 向后滚动特定的轴到一个特定位置 | axis:要向后滚动的轴,其它轴的相对位置不会改变 |
numpy.swapaxes(arr, axis1, axis2) | 交换数组的两个轴 | axis1:对应第一个轴的整数,axis2:对应第二个轴的整数 |
a = np.arange(12).reshape(3,4)
print (a )
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
print (np.transpose(a))
# [[ 0 4 8]
# [ 1 5 9]
# [ 2 6 10]
# [ 3 7 11]]
函数 | 描述 | 备注 |
---|---|---|
numpy.expand_dims(arr, axis) | 通过在指定位置插入新的轴来扩展数组形状 | axis:新轴插入的位置 |
numpy.squeeze(arr, axis) | 从给定数组的形状中删除一维的条目 |
x = np.array(([1,2],[3,4]))
y = np.expand_dims(x, axis = 0)
print (x.shape, y.shape)
# (2, 2) (1, 2, 2)
y = np.expand_dims(x, axis = 1)
print (x.shape, y.shape)
# (2, 2) (2, 1, 2)
x = np.arange(9).reshape(1,3,3)
y = np.squeeze(x)
print (x.shape, y.shape)
# (1, 3, 3) (3, 3)
函数 | 描述 | 备注 |
---|---|---|
numpy.concatenate((a1, a2, …), axis) | 沿指定轴连接相同形状的两个或多个数组 | a1, a2, …:(对于axis)相同类型的数组axis:沿着它连接数组的轴,默认为 0,concatenate不会增加维度,只是简单地完成拼接 |
numpy.stack(arrays, axis) | 沿新轴连接数组序列 | stack会增加一个维度 |
numpy.hstack | numpy.stack 函数的变体,它通过水平堆叠来生成数组 | |
numpy.vstack | numpy.stack 函数的变体,它通过垂直堆叠来生成数组 |
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])
print (np.concatenate((a,b)))
# [[1 2]
# [3 4]
# [5 6]
# [7 8]]
print (np.concatenate((a,b),axis = 1))
# [[1 2 5 6]
# [3 4 7 8]]
print (np.stack((a,b),0))
# [[[1 2]
# [3 4]]
# [[5 6]
# [7 8]]]
print (np.stack((a,b),1))
# [[[1 2]
# [5 6]]
# [[3 4]
# [7 8]]]
函数 | 描述 | 备注 |
---|---|---|
numpy.split(ary, indices_or_sections, axis) | 沿特定的轴将数组分割为子数组 | indices_or_sections:果是一个整数,就用该数平均切分,如果是一个数组,为沿轴切分的位置(左开右闭),axis:沿着哪个维度进行切向,默认为0,横向切分。为1时,纵向切分 |
numpy.hsplit | 用于水平轴分割数组,通过指定要返回的相同形状的数组数量来拆分原数组 | 竖着切 |
numpy.vsplit | 沿着垂直轴分割 | 横着切 |
函数 | 描述 | 备注 |
---|---|---|
numpy.resize(arr, shape) | 返回指定大小的新数组 | 如果新数组大小大于原始大小,则包含原始数组中的元素的副本 |
numpy.append(arr, values, axis=None) | 在数组的末尾添加值。 追加操作会分配整个数组,并把原来的数组复制到新数组中。 | 输入数组的维度必须匹配否则将生成ValueError |
numpy.insert(arr, obj, values, axis) | 在给定索引之前,沿给定轴在输入数组中插入值 | 如果未提供轴参数,则输入数组将展开 |
Numpy.delete(arr, obj, axis) | 返回从输入数组中删除指定子数组的新数组 | 如果未提供轴参数,则输入数组将展开 |
numpy.unique(arr, return_index, return_inverse, return_counts) | 去除数组中的重复元素 |
以下函数用于对 dtype 为 numpy.string_ 或 numpy.unicode_ 的数组执行向量化字符串操作。 它们基于 Python 内置库中的标准字符串函数。这些函数在字符数组类(numpy.char)中定义。
函数 | 描述 | 备注 |
---|---|---|
numpy.char.add() | 依次对两个数组的元素进行字符串连接 | |
numpy.char.multiply() | 多重连接 | |
numpy.char.center() | 将字符串居中,并使用指定字符在左侧和右侧进行填充 | |
numpy.char.capitalize() | 将字符串的第一个字母转换为大写 | |
numpy.char.title() | 将字符串的每个单词的第一个字母转换为大写 | |
numpy.char.lower() | 对数组的每个元素转换为小写 | 它对每个元素调用 str.lower |
numpy.char.upper() | 对数组的每个元素转换为大写 | 它对每个元素调用 str.upper |
numpy.char.split() | 通过指定分隔符对字符串进行分割,并返回数组。 | 默认情况下,分隔符为空格 |
numpy.char.splitlines() | 以换行符作为分隔符来分割字符串,并返回数组 | 换行符 \n |
numpy.char.strip() | 移除开头或结尾处的特定字符 | |
numpy.char.join() | 通过指定分隔符来连接数组中的元素或字符串 | |
numpy.char.replace() | 使用新字符串替换字符串中的所有子字符串 | |
使用新字符串替换字符串中的所有子字符串 | 对数组中的每个元素调用 str.encode 函数。 默认编码是 utf-8,可以使用标准 Python 库中的编解码器 | |
numpy.char.decode() | 对编码的元素进行 str.decode() 解码 |
# 分隔符为 .
print (np.char.split ('www.runoob.com', sep = '.'))
# ['www', 'runoob', 'com']
# 移除数组元素头尾的 a 字符
print (np.char.strip(['arunooba','admin','java'],'a'))
# ['runoob' 'dmin' 'jav']
# 操作字符串
print (np.char.join(':','runoob'))
# r:u:n:o:o:b
# 指定多个分隔符操作数组元素
print (np.char.join([':','-'],['runoob','google']))
# ['r:u:n:o:o:b' 'g-o-o-g-l-e']
sin()、cos()、tan(),
arcsin,arccos,和 arctan 函数
numpy.around() 函数返回指定数字的四舍五入值
numpy.floor() 返回数字的下舍整数
numpy.ceil() 返回数字的上入整数
NumPy 算术函数包含简单的加减乘除: add(),subtract(),multiply() 和 divide()
numpy.reciprocal() 函数返回参数逐元素的倒数
numpy.power()函数将第一个输入数组中的元素作为底数,计算它与第二个输入数组中相应元素的幂
numpy.mod() 计算输入数组中相应元素的相除后的余数。 函数 numpy.remainder() 也产生相同的结果。
函数 | 描述 | 备注 |
---|---|---|
numpy.amin() | 计算数组中的元素沿指定轴的最小值 | |
numpy.amax() | 计算数组中的元素沿指定轴的最大值 | |
numpy.ptp() | 计算数组中元素最大值与最小值的差(最大值 - 最小值) | |
numpy.percentile(a, q, axis) | 计算百分位数 | q: 要计算的百分位数,在 0 ~ 100 之间 |
numpy.median() | 计算数组 a 中元素的中位数 | |
numpy.mean() | 返回数组中元素的算术平均值 | 沿轴的元素的总和除以元素的数量 |
numpy.average() | 根据在另一个数组中给出的各自的权重计算数组中元素的加权平均值 | |
np.std() | 求标准差 | |
np.var() | 求方差 |
a = np.array([1,2,3,4])
print (np.average(a,weights = wts))
# 2.0
函数 | 描述 | 备注 |
---|---|---|
numpy.sort(a, axis, kind, order) | 返回输入数组的排序副本 | axis: 沿着它排序数组的轴,如果没有数组会被展开,沿着最后的轴排序, axis=0 按列排序,axis=1 按行排序 |
numpy.argsort() | 返回的是数组值从小到大的索引值 | |
numpy.lexsort() | 对多个序列进行排序 | 每一列代表一个序列,排序时优先照顾靠后的列 |
numpy.argmax() , numpy.argmin() | 分别沿给定轴返回最大和最小元素的索引 | |
numpy.nonzero() | 返回输入数组中非零元素的索引 | 若原数组维度为n,则返回n个一维array,表示每个轴上对应的坐标 |
numpy.where() | 返回输入数组中满足给定条件的元素的索引 | 若原数组维度为n,则返回n个一维array,表示每个轴上对应的坐标 |
numpy.extract() | 根据某个条件从数组中抽取元素,返回满条件的元素 | 相比于where返回索引,extract直接提取 |
a = np.array([[30,40,70],[80,20,10],[50,90,60]])
print (np.argmax(a))
# 7
print(np.argmax(a, axis = 0) )
# [1 2 0]
print( np.argmax(a, axis = 1) )
# [2 0 1]
x = np.arange(9.).reshape(3, 3)
y = np.where(x > 3)
print(y)
# (array([1, 1, 2, 2, 2]), array([1, 2, 0, 1, 2]))
# 使用这些索引来获取满足条件的元素,,返回一维array
print (x[y])
x = np.arange(9.).reshape(3, 3)
condition = np.mod(x,2) == 0
print (np.extract(condition, x))
# [0. 2. 4. 6. 8.]
副本是一个数据的完整的拷贝,如果我们对副本进行修改,它不会影响到原始数据,物理内存不在同一位置。
副本一般发生在:
视图是数据的一个别称或引用,通过该别称或引用亦便可访问、操作原有数据,但原有数据不会产生拷贝。如果我们对视图进行修改,它会影响到原始数据,物理内存在同一位置。
视图一般发生在:
NumPy 中包含了一个矩阵库 numpy.matlib,该模块中的函数返回的是一个矩阵,而不是 ndarray 对象。
一个m✖n 的矩阵是一个由m行(row)n列(column)元素排列成的矩形阵列。
矩阵里的元素可以是数字、符号或数学式。以下是一个由 6 个数字元素构成的 2 行 3 列的矩阵:
函数 | 描述 | 备注 |
---|---|---|
matlib.empty() | 返回一个新的矩阵 | |
numpy.matlib.empty(shape, dtype, order) | 返回一个新的矩阵 | shape: 定义新矩阵形状的整数或整数元组dtype: 可选,数据类型 |
numpy.matlib.zeros() | 创建一个以 0 填充的矩阵 | |
numpy.matlib.ones() | 创建一个以 1 填充的矩阵 | |
numpy.matlib.eye() | 返回一个矩阵,对角线元素为 1,其他位置为零 | |
numpy.matlib.identity() | 返回给定大小的单位矩阵 | 单位矩阵是个方阵,从左上角到右下角的对角线(称为主对角线)上的元素均为 1,除此以外全都为 0 |
numpy.matlib.rand() | 创建一个给定大小的矩阵,数据是随机填充的 |
NumPy 提供了线性代数函数库 linalg,该库包含了线性代数所需的所有功能
函数 | 描述 | 备注 |
---|---|---|
numpy.dot(a, b, out=None) | 两个数组的点积,即元素对应相乘 | 对于两个一维的数组,计算的是这两个数组对应下标元素的乘积和(数学上称之为内积);对于二维数组,计算的是两个数组的矩阵乘积;对于多维数组,它的通用计算公式如下,即结果数组中的每个元素都是:数组a的最后一维上的所有元素与数组b的倒数第二位上的所有元素的乘积和: dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m]) |
numpy.inner() | 返回一维数组的向量内积。对于更高的维度,它返回最后一个轴上的和的乘积 | |
numpy.matmul() | 返回两个数组的矩阵乘积 | |
numpy.linalg.det() | 计算输入矩阵的行列式 | |
numpy.linalg.solve() | 给出了矩阵形式的线性方程的解 | |
numpy.linalg.inv() | 计算矩阵的乘法逆矩阵 |
Numpy 可以读写磁盘上的文本数据或二进制数据。
NumPy 为 ndarray 对象引入了一个简单的文件格式:npy。
npy 文件用于存储重建 ndarray 所需的数据、图形、dtype 和其他信息。
常用的 IO 函数有:
函数 | 描述 | 备注 |
---|---|---|
numpy.save(file, arr, allow_pickle=True, fix_imports=True) | 将数组保存到以 .npy 为扩展名的文件中 | allow_pickle: 可选,布尔值,允许使用 Python pickles 保存对象数组,Python 中的 pickle 用于在保存到磁盘文件或从磁盘文件读取之前,对对象进行序列化和反序列化 |
numpy.savez(file, *args, **kwds) | 将多个数组保存到以 npz 为扩展名的文件中 | args: 要保存的数组,可以使用关键字参数为数组起一个名字,非关键字参数传递的数组会自动起名为 arr_0, arr_1, kwds: 要保存的数组使用关键字名称 |
np.savetxt(FILENAME, a, fmt="%d", delimiter=",") | 以简单的文本文件格式存储数据 | 参数 delimiter 可以指定各种分隔符、针对特定列的转换器函数、需要跳过的行数等 |
a = np.array([1,2,3,4,5])
# 保存到 outfile.npy 文件上
np.save('outfile.npy',a)
# 保存到 outfile2.npy 文件上,如果文件路径末尾没有扩展名 .npy,该扩展名会被自动加上
np.save('outfile2',a)
a = np.array([[1,2,3],[4,5,6]])
b = np.arange(0, 1.0, 0.1)
c = np.sin(b)
# c 使用了关键字参数 sin_array
np.savez("runoob.npz", a, b, sin_array = c)
r = np.load("runoob.npz")
print(r.files) # 查看各个数组名称
# ['sin_array', 'arr_0', 'arr_1']
print(r["arr_0"]) # 数组 a
print(r["arr_1"]) # 数组 b
print(r["sin_array"]) # 数组 c