术语表#
- (n,)#
括号中的数字后跟逗号表示包含一个元素的元组。尾部的逗号将一个元素的元组与括号中的
n
区分开来。- -1#
在维度条目中,指示 NumPy 选择保持数组元素总数不变的长度。
>>> np.arange(12).reshape(4, -1).shape (4, 3)
在索引中,任何负值 表示 从右侧进行索引。
- …#
一个
Ellipsis
。在索引数组时,表示缺失的轴(如果存在)为完整切片。
>>> a = np.arange(24).reshape(2,3,4)
>>> a[...].shape (2, 3, 4)
>>> a[...,0].shape (2, 3)
>>> a[0,...].shape (3, 4)
>>> a[0,...,0].shape (3,)
它最多可以使用一次;
a[...,0,...]
会引发IndexError
。在打印输出中,NumPy 使用
...
替换大型数组中间的元素。要查看整个数组,请使用numpy.printoptions
- :#
Python 的 切片 运算符。在 ndarray 中,切片可以应用于每个轴
>>> a = np.arange(24).reshape(2,3,4) >>> a 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]]]) >>> a[1:,-2:,:-1] array([[[16, 17, 18], [20, 21, 22]]])
可以省略尾部的切片
>>> a[1] == a[1,:,:] array([[ True, True, True, True], [ True, True, True, True], [ True, True, True, True]])
与 Python 中切片创建副本不同,在 NumPy 中切片创建 视图。
有关详细信息,请参见 组合高级索引和基本索引。
- <#
在 dtype 声明中,表示数据为 小端序(括号在右侧较大)。
>>> dt = np.dtype('<f') # little-endian single-precision float
- >#
在 dtype 声明中,表示数据为 大端序(括号在左侧较大)。
>>> dt = np.dtype('>H') # big-endian unsigned short
- 高级索引#
- 沿轴#
数组
a
沿轴 n 的操作表现得好像其参数是a
的切片数组,其中每个切片都有轴 n 的连续索引。例如,如果
a
是一个 3 x N 数组,沿轴 0 的操作表现得好像其参数是一个包含每一行的切片的数组>>> np.array((a[0,:], a[1,:], a[2,:]))
为了具体化,我们可以选择操作为数组反转函数
numpy.flip
,它接受一个axis
参数。我们构造一个 3 x 4 数组a
>>> a = np.arange(12).reshape(3,4) >>> a array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])
沿轴 0(行轴)反转得到
>>> np.flip(a,axis=0) array([[ 8, 9, 10, 11], [ 4, 5, 6, 7], [ 0, 1, 2, 3]])
回顾沿轴的定义,沿轴 0 的
flip
将其参数视为>>> np.array((a[0,:], a[1,:], a[2,:])) array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])
并且
np.flip(a,axis=0)
的结果是对切片进行反转>>> np.array((a[2,:],a[1,:],a[0,:])) array([[ 8, 9, 10, 11], [ 4, 5, 6, 7], [ 0, 1, 2, 3]])
- 数组#
在 NumPy 文档中与 ndarray 同义。
- 类数组#
任何可以解释为 ndarray 的 标量 或 序列。除了 ndarray 和标量外,此类别还包括列表(可能是嵌套的,并且具有不同的元素类型)和元组。 numpy.array 接受的任何参数都是类数组。
>>> a = np.array([[1, 2.0], [0, 0], (1+1j, 3.)]) >>> a array([[1.+0.j, 2.+0.j], [0.+0.j, 0.+0.j], [1.+1.j, 3.+0.j]])
- 数组标量#
一个 数组标量 是类型/类 float32、float64 等的实例。为了在处理操作数时保持一致性,NumPy 将标量视为零维数组。相反,零维数组是包含一个值的 ndarray 实例。
- 轴#
数组维度的另一个术语。轴从左到右编号;轴 0 是形状元组中的第一个元素。
在二维向量中,轴 0 的元素是行,轴 1 的元素是列。
在更高维度中,情况有所变化。NumPy 将更高维度的向量打印为行和列构建块的复制,如以下三维向量所示
>>> a = np.arange(12).reshape(2,2,3) >>> a array([[[ 0, 1, 2], [ 3, 4, 5]], [[ 6, 7, 8], [ 9, 10, 11]]])
a
被描绘为一个包含两个元素的数组,这些元素是 2x3 向量。从这个角度来看,行和列分别是任何形状中的最后两个轴。此规则有助于您预测向量将如何打印,反之亦然,如何找到任何打印元素的索引。例如,在示例中,8 的最后两个值的索引必须为 0 和 2。由于 8 出现在两个 2x3 中的第二个,因此第一个索引必须为 1
>>> a[1,0,2] 8
在打印的向量中计算维度的一种便捷方法是计算开括号后的
[
符号。这在区分例如 (1,2,3) 形状和 (2,3) 形状时很有用>>> a = np.arange(6).reshape(2,3) >>> a.ndim 2 >>> a array([[0, 1, 2], [3, 4, 5]])
>>> a = np.arange(6).reshape(1,2,3) >>> a.ndim 3 >>> a array([[[0, 1, 2], [3, 4, 5]]])
- .base#
如果数组不拥有自己的内存,那么它的 base 属性将返回该数组引用的内存所在的对象。该对象可能引用来自另一个对象的内存,因此拥有对象可能为
a.base.base.base...
。一些作者错误地声称测试base
可以确定数组是否是 视图。有关正确方法,请参见numpy.shares_memory
。- 大端序#
请参见 字节序。
- BLAS#
- 广播#
广播 是 NumPy 处理不同大小的 ndarray 的能力,就好像它们都是相同的大小一样。
它允许一种优雅的“意图即行为”方式,例如,将标量添加到向量会将标量值添加到每个元素。
>>> a = np.arange(3) >>> a array([0, 1, 2])
>>> a + [3, 3, 3] array([3, 4, 5])
>>> a + 3 array([3, 4, 5])
通常,向量操作数的大小必须相同,因为 NumPy 逐元素进行操作 - 例如,
c = a * b
为c[0,0,0] = a[0,0,0] * b[0,0,0] c[0,0,1] = a[0,0,1] * b[0,0,1] ...
但在某些有用的情况下,NumPy 可以在“缺失”的轴或“过短”的维度上复制数据,以便形状匹配。复制不需要额外的内存或时间。有关详细信息,请参见 广播。
- C 顺序#
与 行优先 相同。
- 转换#
将数组数据从一种 dtype 转换为另一种 dtype 的过程。存在几种转换模式,由以下转换规则定义
no
:数据类型不应转换。数组之间的数据类型不匹配将引发 TypeError。equiv
:仅允许字节序更改。safe
:仅允许可以保留值的转换。允许向上转换(例如,从整数到浮点数),但不允许向下转换。same_kind
:‘same_kind’ 转换选项允许安全转换和在同类中的转换,例如 float64 到 float32。unsafe
:可以进行任何数据转换。
- 列优先#
请参见 行优先和列优先顺序。
- 连续#
如果数组满足以下条件,则为连续的
它占用一个完整的内存块,并且
索引更高的数组元素占用更高的地址(也就是说,没有 步幅 为负)。
有两种类型的适当连续 NumPy 数组
Fortran 连续数组是指按列存储的数据,即数据在内存中的存储索引从最低维度开始;
C 连续,或简称为连续数组,是指按行存储的数据,即数据在内存中的存储索引从最高维度开始。
对于一维数组,这些概念是相同的。
例如,一个 2x2 数组
A
如果其元素在内存中以以下顺序存储,则为 Fortran 连续的A[0,0] A[1,0] A[0,1] A[1,1]
如果顺序如下,则为 C 连续的
A[0,0] A[0,1] A[1,0] A[1,1]
要测试数组是否为 C 连续的,请使用 NumPy 数组的
.flags.c_contiguous
属性。要测试 Fortran 连续性,请使用.flags.f_contiguous
属性。- 副本#
请参见 视图。
- 维度#
请参见 轴。
- dtype#
描述 ndarray 中(类型相同的)元素的数据类型。它可以更改以重新解释数组内容。有关详细信息,请参见 数据类型对象 (dtype)。
- 花式索引#
是 高级索引 的另一个术语。
- 字段#
在 结构化数据类型 中,每个子类型称为 字段。 字段 具有名称(字符串)、类型(任何有效的 dtype)以及可选的 标题。请参见 数据类型对象 (dtype)。
- Fortran 顺序#
与 列优先 相同。
- 扁平化#
请参见 展平。
- 同构#
同构数组的所有元素都具有相同的类型。 ndarray 与 Python 列表不同,是同构的。类型可以很复杂,例如在 结构化数组 中,但所有元素都具有该类型。
NumPy 的 对象数组 包含对 Python 对象的引用,它充当异构数组的角色。
- itemsize#
dtype 元素的大小(以字节为单位)。
- 小端序#
请参见 字节序。
- 掩码#
用于为操作选择特定元素的布尔数组
>>> x = np.arange(5) >>> x array([0, 1, 2, 3, 4])
>>> mask = (x > 2) >>> mask array([False, False, False, True, True])
>>> x[mask] = -1 >>> x array([ 0, 1, 2, -1, -1])
- 掩码数组#
可以通过将错误数据或缺失数据放在掩码数组中来干净地忽略它,该数组包含一个内部布尔数组,指示无效条目。对掩码数组的操作会忽略这些条目。
>>> a = np.ma.masked_array([np.nan, 2, np.nan], [True, False, True]) >>> a masked_array(data=[--, 2.0, --], mask=[ True, False, True], fill_value=1e+20) >>> a + [1, 2, 3] masked_array(data=[--, 4.0, --], mask=[ True, False, True], fill_value=1e+20)
有关详细信息,请参见 掩码数组。
- 矩阵#
NumPy 的二维 矩阵类 不应再使用;请使用常规的 ndarray。
- ndarray#
- 对象数组#
一个数据类型为
object
的数组,即它包含对 Python 对象的引用。对数组进行索引会解除对 Python 对象的引用,因此与其他 ndarray 不同,对象数组可以保存异构对象。- 展平#
numpy.ravel 和 numpy.flatten 都可以展平一个 ndarray。
ravel
如果可能,将返回一个视图;flatten
总是返回一个副本。展平将一个多维数组压缩为一个单维度;如何执行此操作的细节(例如,
a[n+1]
应该是下一行还是下一列)是参数。- 记录数组#
一个 结构化数组,允许以属性方式访问(
a.field
),除了a['field']
之外。有关详细信息,请参阅 numpy.recarray.- 行优先#
请参阅 行优先和列优先顺序。NumPy 默认情况下以行优先顺序创建数组。
- 标量#
在 NumPy 中,通常是 数组标量 的同义词。
- 形状#
一个元组,显示 ndarray 每个维度的长度。元组本身的长度是维数的数量(numpy.ndim)。元组元素的乘积是数组中的元素数量。有关详细信息,请参阅 numpy.ndarray.shape。
- 步长#
物理内存是一维的;步长提供了一种将给定索引映射到内存地址的机制。对于一个 N 维数组,其
strides
属性是一个 N 元素元组;从索引i
到索引i+1
在轴n
上前进意味着向地址添加a.strides[n]
字节。步长是从数组的 dtype 和形状自动计算的,但可以使用 as_strided. 直接指定。
有关详细信息,请参阅 numpy.ndarray.strides。
要了解步长如何构成 NumPy 视图能力的基础,请参阅 NumPy 数组:一种用于高效数值计算的结构。
- 结构化数组#
- 结构化数据类型#
用户可以创建任意复杂的 dtypes,其中可以包含其他数组和 dtypes。这些复合 dtypes 称为 结构化数据类型。
- 子数组#
嵌套在 结构化数据类型 中的数组,就像这里的
b
一样>>> dt = np.dtype([('a', np.int32), ('b', np.float32, (3,))]) >>> np.zeros(3, dtype=dt) array([(0, [0., 0., 0.]), (0, [0., 0., 0.]), (0, [0., 0., 0.])], dtype=[('a', '<i4'), ('b', '<f4', (3,))])
- 子数组数据类型#
结构化数据类型的一个元素,它表现得像一个 ndarray。
- 标题#
结构化数据类型中字段名称的别名。
- 类型#
- ufunc#
NumPy 的快速逐元素计算(向量化)提供了对要应用的函数的选择。该函数的一般术语是
ufunc
,即universal function
的缩写。NumPy 例程具有内置的 ufuncs,但用户也可以 编写自己的 ufuncs。- 向量化#
NumPy 将数组处理交给 C 处理,在 C 中,循环和计算的速度比 Python 快得多。为了利用这一点,使用 NumPy 的程序员消除了 Python 循环,转而使用数组到数组的操作。向量化 可以指 C 卸载,也可以指构建 NumPy 代码以利用 C 卸载。
- 视图#
NumPy 可以不触碰底层数据,就能使一个数组看起来改变其数据类型和形状。
这样创建的数组是一个 视图,NumPy 通常利用使用视图而不是创建新数组的性能优势。
潜在的缺点是,写入视图也会改变原始数组。如果这是一个问题,NumPy 需要创建一个物理上不同的数组——一个
copy
。一些 NumPy 例程总是返回视图,一些总是返回副本,一些可能返回视图或副本,而对于一些例程,可以选择。管理视图和副本的责任落在了程序员身上。
numpy.shares_memory
将检查b
是否是a
的视图,但确切的答案并不总是可行的,如文档页面所述。>>> x = np.arange(5) >>> x array([0, 1, 2, 3, 4])
>>> y = x[::2] >>> y array([0, 2, 4])
>>> x[0] = 3 # changing x changes y as well, since y is a view on x >>> y array([3, 2, 4])