词汇表#

(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 的 切片 操作符。在 ndarrays 中,切片可以应用于每个轴。

>>> 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 的 标量序列。除了 ndarrays 和标量之外,此类别还包括列表(可能嵌套且具有不同元素类型)和元组。 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 将标量视为零维数组。相比之下,0 维数组是一个包含恰好一个值的 ndarray 实例。

#

数组维度的另一个术语。轴从左到右编号;轴 0 是 shape 元组中的第一个元素。

在二维向量中,轴 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#

Basic Linear Algebra Subprograms(基础线性代数子程序)

广播#

广播是 NumPy 处理不同大小的 ndarrays 的能力,就好像它们的大小相同一样。

它允许一种优雅的“你期望做什么就做什么”的行为,例如,将一个标量添加到向量中会将其值添加到每个元素。

>>> 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:只允许可以保留值的转换。允许上转换为(例如,从 int 到 float),但不允许下转换为。

  • 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 顺序#

列主序 相同。

展平#

请参阅 ravel

同质#

同质数组的所有元素都具有相同的类型。与 Python 列表相比,ndarray 是同质的。类型可能很复杂,例如在 结构化数组 中,但所有元素都具有该类型。

NumPy 的 对象数组,包含对 Python 对象的引用,充当异质数组的角色。

项大小#

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 的二维 矩阵类 不应再使用;请使用常规 ndarrays。

ndarray#

NumPy 的基本结构。.

对象数组#

dtype 为 object 的数组;也就是说,它包含对 Python 对象的引用。索引数组会解引用 Python 对象,因此与其他 ndarrays 不同,对象数组能够容纳异质对象。

ravel#

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 元素元组;在轴 n 上从索引 i 推进到索引 i+1 意味着将 a.strides[n] 字节添加到地址。

步幅是根据数组的 dtype 和 shape 自动计算的,但也可以通过 as_strided 直接指定。

有关详细信息,请参阅 numpy.ndarray.strides

要了解步幅如何支撑 NumPy 视图的力量,请参阅 NumPy 数组:高效数值计算的结构。

结构化数组#

dtype结构化数据类型 的数组。

结构化数据类型#

用户可以创建任意复杂的 dtype,其中可以包含其他数组和 dtype。这些复合 dtype 被称为 结构化数据类型。

子数组#

嵌套在 结构化数据类型 中的数组,如下面的 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。

标题#

结构化数据类型中字段名称的别名。

类型#

在 NumPy 中,通常是 dtype 的同义词。对于更广泛的 Python 含义,请参阅 这里

通用函数#

NumPy 的快速逐元素计算(向量化)提供了函数选择。函数的通用术语是 ufunc,是 universal function(通用函数)的缩写。NumPy 例程内置了 ufuncs,但用户也可以 编写自己的。

向量化#

NumPy 将数组处理交给 C,那里的循环和计算比 Python 快得多。为了利用这一点,使用 NumPy 的程序员会消除 Python 循环,转而使用数组到数组的操作。向量化 可以同时指代 C 的卸载以及结构化 NumPy 代码以利用它。

视图#

在不触及底层数据的情况下,NumPy 可以让一个数组改变其数据类型和形状。

这样创建的数组是一个视图,NumPy 经常利用使用视图而不是创建新数组的性能优势。

一个潜在的缺点是,写入视图可能会改变原始数据。如果这是一个问题,NumPy 需要创建物理上不同的数组——一个 副本

一些 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])