N 维数组 (ndarray)#

ndarray 是一个(通常是固定大小的)多维容器,其中包含相同类型和大小的项目。数组中的维度和项目数由其 shape 定义,它是一个 tuple,其中包含 N 个非负整数,指定每个维度的尺寸。数组中项目的类型由单独的 数据类型对象 (dtype) 指定,每个 ndarray 都与其中一个关联。

与 Python 中的其他容器对象一样,可以通过对数组进行ndarray(例如,使用N个整数)的索引或切片和通过ndarray的方法和属性来访问和修改ndarray的内容。

不同的ndarray可以共享相同的数据,因此在一个ndarray中所做的更改可能会在另一个ndarray中可见。也就是说,一个 ndarray 可以成为另一个 ndarray 的“视图”,并且它所引用的数据是由“基”ndarray 来处理的。ndarray 也可以是归 Python字符串或实现内存视图数组接口的对象所拥有的内存的视图。

示例

一个 2 x 3 大小的二维数组,由 4 字节整数元素组成

>>> import numpy as np
>>> x = np.array([[1, 2, 3], [4, 5, 6]], np.int32)
>>> type(x)
<class 'numpy.ndarray'>
>>> x.shape
(2, 3)
>>> x.dtype
dtype('int32')

可以使用类似 Python 容器的语法对数组进行索引

>>> # The element of x in the *second* row, *third* column, namely, 6.
>>> x[1, 2]
   6

例如,切片可以生成数组的视图

>>> y = x[:,1]
>>> y
array([2, 5], dtype=int32)
>>> y[0] = 9 # this also changes the corresponding element in x
>>> y
array([9, 5], dtype=int32)
>>> x
array([[1, 9, 3],
       [4, 5, 6]], dtype=int32)

构建数组#

可以使用数组创建例程中详细介绍的例程以及低级来构建新数组ndarray构造器

ndarray(shape[, dtype, buffer, offset, ...])

数组对象表示一个多维的、同质的固定大小项的数组。

索引数组#

可以使用扩展的 Python 切片语法array[selection]对数组进行索引。类似的语法也用于访问结构化数据类型中的字段。

另请参阅

数组索引.

ndarray 的内部存储器布局#

ndarray 的一个实例包括一段计算机存储器的连续一维段(由数组所有,或由其他某些对象所有),以及一个索引方案,它把N 个整数映射到块中的一个项目的位置。索引可以变化的范围由数组的 shape 规定。每个项目占用多少字节以及如何解释这些字节是由与该数组相关联的 数据类型对象 定义的。

内存段本质上是一维的,并且有很多不同的方案可用于把一个N 维数组的项目排列在一个一维块中。NumPy 具有灵活性,ndarray 对象可以容纳任何步长索引方案。在步长方案中,N 维索引 \((n_0, n_1, ..., n_{N-1})\) 对应于与该数组相关联的存储器块开始的偏移量(以字节为单位)

\[n_{\mathrm{offset}} = \sum_{k=0}^{N-1} s_k n_k\]

因此,\(s_k\) 为整数,指定该数组的 strides列优先 顺序(例如,在 Fortran 语言和Matlab 中使用)和 行优先 顺序(在 C 中使用)方案仅仅是步长方案的特定的种类,对应于可以通过步长寻址的存储器

\[s_k^{\mathrm{column}} = \mathrm{itemsize} \prod_{j=0}^{k-1} d_j , \quad s_k^{\mathrm{row}} = \mathrm{itemsize} \prod_{j=k+1}^{N-1} d_j .\]

其中 \(d_j\) = self.shape[j]

C 顺序和 Fortran 顺序都是 连续的例如,单段存储器布局,通过某些索引组合可以访问存储器块的每一部分。

备注

连续数组单段数组是同义词,在文档中可互换使用。

虽然具有相应的标志设置的 C 风格和 Fortran 风格的连续数组可以通过上述步长进行寻址,但实际步长可能不同。这可能在两种情况下发生

  1. 如果 self.shape[k] == 1 那么对于任何索引 index[k] == 0。这意味着在偏移量公式 \(n_k = 0\)\(s_k n_k = 0\)\(s_k\) 的值 = self.strides[k] 是任意的。

  2. 如果一个数组没有元素 (self.size == 0) 将没有合法的索引,且跨度从未使用过。任何没有元素的数组可以认为是 C 样式和 Fortran 样式的连续数组。

第 1 点意味着 selfself.squeeze() 总是有相同的连续性和 aligned 标志值。这也意味着即使一个高维数组,也可能同时是 C 样式和 Fortran 样式的连续数组。

如果所有元素及自身的基本偏移量的内存偏移量都是 self.itemsize 的倍数,那么这个数组被认为是对齐的。了解内存对齐有助于提高大多数硬件的性能。

警告

通常情况下,对于 C 样式连续的数组,self.strides[-1] == self.itemsize 不成立,对于 Fortran 样式连续的数组,self.strides[0] == self.itemsize 不成立。

除非另行指定,否则新 ndarrays 中的数据按 行优先 (C) 顺序排列,但是,比如 基本数组切片 通常会按照不同的方案产生 视图

备注

NumPy 中的若干算法可处理跨度任意的数组。但是,一些算法需要单段数组。当将跨度不规则的数组传递到此类算法中时,将自动进行复制。

数组属性#

数组属性会反映数组本身所固有的信息。通常,通过属性访问数组使您可以获取并有时设置数组的固有属性,而无需创建新数组。公开的属性是数组的核心部分,其中只有一些可以在不创建新数组的情况下有意义地进行重置。以下是有关每个属性的信息。

内存布局#

以下属性包含有关数组内存布局的信息

ndarray.flags

有关数组内存布局的信息。

ndarray.shape

数组维数的元组。

ndarray.strides

遍历数组时每个维度中步长的字节元组。

ndarray.ndim

数组维数。

ndarray.data

指向数组数据开头的 Python 缓冲区对象。

ndarray.size

数组中的元素数量。

ndarray.itemsize

单个数组元素的字节长度。

ndarray.nbytes

数组元素消耗的总字节数。

ndarray.base

如果内存来自其他对象,则使用基本对象。

数据类型#

另请参阅

数据类型对象

可以使用 dtype 属性找到与数组关联的数据类型对象

ndarray.dtype

数组元素的数据类型。

其他属性#

ndarray.T

转置数组的视图。

ndarray.real

数组的实部。

ndarray.imag

数组的虚部。

ndarray.flat

数组上的 1 维迭代器。

数组接口#

另请参阅

数组接口协议.

__array_interface__

数组接口的 Python 端

__array_struct__

数组接口的 C 端

ctypes 外部函数接口#

ndarray.ctypes

用于简化数组与 ctypes 模块交互的对象。

数组方法#

ndarray 对象有许多方法用于或以某种方式对数组进行操作,通常返回数组结果。对这些方法的简要说明如下。(每个方法的文档字符串都有更完整的说明。)

For the following methods there are also corresponding functions in numpy: all, any, argmax, argmin, argpartition, argsort, choose, clip, compress, copy, cumprod, cumsum, diagonal, imag, max, mean, min, nonzero, partition, prod, put, ravel, real, repeat, reshape, round, searchsorted, sort, squeeze, std, sum, swapaxes, take, trace, transpose, var.

数组转换#

ndarray.item(*args)

将数组中的一个元素复制到标准 Python 标量并返回。

ndarray.tolist()

将数组返回为 Python 标量的 a.ndim 层深度嵌套列表。

ndarray.tostring([order])

与行为完全相同的 tobytes 的兼容别名。

ndarray.tobytes([order])

构造包含数组中原始数据字节的 Python 字节。

ndarray.tofile(fid[, sep, format])

将数组写入文件作为文本或二进制(默认)。

ndarray.dump(file)

将数组的 pickle 存储到指定的文件中。

ndarray.dumps()

将数组的 pickle 返回为字符串。

ndarray.astype(dtype[, order, casting, ...])

数组的副本,强制转换为指定类型。

ndarray.byteswap([inplace])

交换数组元素的字节

ndarray.copy([order])

返回数组的副本。

ndarray.view([dtype][, type])

具有相同数据的数组的新视图。

ndarray.getfield(dtype[, offset])

将给定数组的一个字段返回为特定类型。

ndarray.setflags([write, align, uic])

分别设置数组标志 WRITEABLE、ALIGNED、WRITEBACKIFCOPY。

ndarray.fill(value)

使用标量值填充数组。

形状操作#

对于 reshape、resize 和 transpose,单个元组参数可以用 n 个整数替换,这将被解释为 n 元组。

ndarray.reshape(shape, /, *[, order, copy])

返回包含相同数据的新形状的数组。

ndarray.resize(new_shape[, refcheck])

改变数组的形状和大小,原址进行。

ndarray.transpose(*axes)

返回具有转置轴的数组视图。

ndarray.swapaxes(axis1, axis2)

返回具有交换的 axis1axis2 的数组视图。

ndarray.flatten([order])

返回坍缩成一维的数组副本。

ndarray.ravel([order])

返回扁平化数组。

ndarray.squeeze([axis])

a 中移除长度为 1 的轴。

项选取和操作#

对于采用 axis 关键字的数组方法,其默认值为 None。如果 axis 为 None,则将数组视为 1-D 数组。axis 的任何其他值都表示该操作应沿其进行的维度。

ndarray.take(indices[, axis, out, mode])

返回由给定索引处的 a 元素形成的数组。

ndarray.put(indices, values[, mode])

为索引中的所有n设置a.flat[n] = values[n]

ndarray.repeat(repeats[, axis])

重复数组的元素。

ndarray.choose(choices[, out, mode])

使用索引数组从一组选择项中构造一个新数组。

ndarray.sort([axis, kind, order])

在原地对数组进行排序。

ndarray.argsort([axis, kind, order])

返回将对该数组进行排序的索引。

ndarray.partition(kth[, axis, kind, order])

对数组中的元素进行部分排序,使 kth 位置的元素值位于排序后的数组中的位置。

ndarray.argpartition(kth[, axis, kind, order])

返回将对该数组进行划分的索引。

ndarray.searchsorted(v[, side, sorter])

找到 v 中的元素在 a 中插入的位置(以维持顺序)。

ndarray.nonzero()

返回非零元素的索引。

ndarray.compress(condition[, axis, out])

返回此数组在给定轴上选择的切片。

ndarray.diagonal([offset, axis1, axis2])

返回指定的对角线。

计算#

这些方法的很多都带一个名为axis的参数。在这种情况下:

  • 如果axisNone(默认值),则将数组视为一维数组并在整个数组上执行操作。如果 self 是零维数组或数组标量,则此行为也是默认行为。(数组标量是 float32、float64 等类型/类的实例,而零维数组是恰好包含一个数组标量的 ndarray 实例。)

  • 如果 axis 是整数,则在给定的轴上执行操作(对于每个可沿着给定轴创建的 1 维子数组)。

axis 参数的示例

大小为 3 x 3 x 3 的三维数组,对其三个轴中的每一个进行求和

>>> import numpy as np
>>> x = np.arange(27).reshape((3,3,3))
>>> x
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],
      [24, 25, 26]]])
>>> x.sum(axis=0)
array([[27, 30, 33],
      [36, 39, 42],
      [45, 48, 51]])
>>> # for sum, axis is the first keyword, so we may omit it,
>>> # specifying only its value
>>> x.sum(0), x.sum(1), x.sum(2)
(array([[27, 30, 33],
      [36, 39, 42],
      [45, 48, 51]]),
array([[ 9, 12, 15],
      [36, 39, 42],
      [63, 66, 69]]),
array([[ 3, 12, 21],
      [30, 39, 48],
      [57, 66, 75]]))

参数 dtype 指定减少操作(如求和)应该在哪种数据类型上进行。默认减少数据类型与 self 的数据类型相同。为了避免溢出,使用更大的数据类型执行减少操作可能很有用。

对于几种方法,也可以提供可选的 out 参数,结果将放置在给定的输出数组中。out 参数必须是 ndarray,并且具有相同数量的元素。它可以有不同的数据类型,在这种情况下将执行类型转换。

ndarray.max([axis, out, keepdims, initial, ...])

返回沿着给定轴的最大值。

ndarray.argmax([axis, out, keepdims])

返回沿给定轴的最大值对应的索引。

ndarray.min([axis, out, keepdims, initial, ...])

返回沿给定轴的最小值。

ndarray.argmin([axis, out, keepdims])

返回沿给定轴的最小值对应的索引。

ndarray.clip([min, max, out])

返回一个值限制在 [min, max] 中的数组。

ndarray.conj()

取所有元素的复共轭。

ndarray.round([decimals, out])

返回已将每个元素四舍五入到给定小数位数的 a

ndarray.trace([offset, axis1, axis2, dtype, out])

返回沿着数组对角线方向的和。

ndarray.sum([axis, dtype, out, keepdims, ...])

在给定轴返回数组元素之和。

ndarray.cumsum([axis, dtype, out])

返回沿给定轴元素的累积和。

ndarray.mean([axis, dtype, out, keepdims, where])

返回沿给定轴数组元素的平均值。

ndarray.var([axis, dtype, out, ddof, ...])

返回沿给定轴数组元素的方差。

ndarray.std([axis, dtype, out, ddof, ...])

返回沿给定轴数组元素的标准差。

ndarray.prod([axis, dtype, out, keepdims, ...])

返回沿给定轴数组元素的乘积

ndarray.cumprod([axis, dtype, out])

返回沿给定轴元素的累积乘积。

ndarray.all([axis, out, keepdims, where])

如果所有元素均为真,则返回 True。

ndarray.any([axis, out, keepdims, where])

如果元素a 中的任何一个为真,则返回 True。

算术、矩阵乘法和比较运算#

ndarrays 数组的算术和比较运算被定义为逐元素运算,通常生成 ndarray 对象作为结果。

所有算术运算(+-*///%divmod()**pow()<<>>&^|~)和比较(==<><=>=!=)等效于 NumPy 的对应万能函数(或简称 UFUNC)。更多信息,请参阅 万能函数 一节。

比较运算符

ndarray.__lt__(value, /)

返回 self<value。

ndarray.__le__(value, /)

返回 self<=value。

ndarray.__gt__(value, /)

返回 self>value。

ndarray.__ge__(value, /)

返回 self>=value。

ndarray.__eq__(value, /)

返回 self==value。

ndarray.__ne__(value, /)

返回 self!=value。

数组的真值(bool()

ndarray.__bool__(/)

如果 self 为 True 则返回 True 否则返回 False

备注

对数组执行真值测试将会调用 ndarray.__bool__,如果数组中元素的数目大于 1,它会引发一个错误,因为此类数组的真值是模棱两可的。使用 .any().all() 来明确在这种情况下含义是什么。(如果元素个数为 0,则数组值变为 False。)

一元运算

算术

ndarray.__add__(value, /)

返回 self+value。

ndarray.__sub__(value, /)

返回 self-value。

ndarray.__mul__(value, /)

返回 self*value。

ndarray.__truediv__(value, /)

返回 self/value。

ndarray.__floordiv__(value, /)

返回 self//value。

ndarray.__mod__(value, /)

返回 self%value。

ndarray.__divmod__(value, /)

返回 divmod(self, value)。

ndarray.__pow__(value[, mod])

返回 pow(self, value, mod)。

ndarray.__lshift__(value, /)

返回 self<<value。

ndarray.__rshift__(value, /)

返回 self>>value。

ndarray.__and__(value, /)

返回 self&value。

ndarray.__or__(value, /)

返回 self|value。

ndarray.__xor__(value, /)

返回 self^value。

备注

  • pow传递的任何第三个参数都被自动忽略,因为它底层的ufunc只接收两个参数。

  • 由于ndarray是一种内置类型(使用 C 语言编写),因此__r{op}__特殊方法没有得到直接定义。

  • 用来实现数组的许多算术特殊方法的函数可以通过__array_ufunc__进行修改。

算术运算(就地计算)

ndarray.__iadd__(value, /)

返回 self+=value。

ndarray.__isub__(value, /)

返回 self-=value。

ndarray.__imul__(value, /)

返回 self*=value。

ndarray.__itruediv__(value, /)

返回 self/=value。

ndarray.__ifloordiv__(value, /)

返回 self//=value。

ndarray.__imod__(value, /)

返回 self%=value。

ndarray.__ipow__(value, /)

返回 self**=value。

ndarray.__ilshift__(value, /)

返回 self<<=value。

ndarray.__irshift__(value, /)

返回 self>>=value。

ndarray.__iand__(value, /)

返回 self&=value。

ndarray.__ior__(value, /)

返回 self|=value。

ndarray.__ixor__(value, /)

返回 self^=value。

警告

就地操作将使用两个操作数的数据类型决定的精度执行计算,但会(如果需要)静默地下降结果(如果需要),以便它可以放回到数组中。因此,对于混合精度计算,A {op}= B 可以不同于 A = A {op} B。例如,假设 a = ones((3,3))。然后,a += 3j 不同于 a = a + 3j:虽然它们都执行相同的计算,a += 3 将结果强制转换成 a,而 a = a + 3j 将名称 a 重新绑定到结果。

矩阵乘法

ndarray.__matmul__(value, /)

返回 self@value

备注

矩阵运算符 @@= 在 Python 3.5 中引入,遵循 PEP 465,运算符 @ 已在 NumPy 1.10.0 中引入。可以在 matmul 文档中找到更多信息。

特殊函数#

对于标准库函数

ndarray.__copy__()

如果 copy.copy 被调用到一个数组时使用。

ndarray.__deepcopy__(memo, /)

如果 copy.deepcopy 被调用到一个数组时使用。

ndarray.__reduce__()

用于 pickle。

ndarray.__setstate__(state, /)

用于 unpickle。

基本定制

ndarray.__new__(*args, **kwargs)

ndarray.__array__([dtype], *[, copy])

如果给定的 dtype 参数未给定或它与数组数据类型匹配,则对于 dtype 参数,它会返回自己新的引用。

ndarray.__array_wrap__(array[, context], /)

返回 array 的视图,类型和 self 一样。

Container 定制:(见 索引

ndarray.__len__(/)

返回 len(self)。

ndarray.__getitem__(key, /)

返回 self[key]。

ndarray.__setitem__(key, value, /)

将 self[key] 设置为 value。

ndarray.__contains__(key, /)

在 self 中返回 key。

转换;操作 int()float()complex()。它们仅对只有一个元素的数组起作用,并返回相应的标量。

字符串表示

ndarray.__str__(/)

返回 str(self)。

ndarray.__repr__(/)

返回 repr(self)。

用于类型化的实用方法

ndarray.__class_getitem__(item, /)

返回 ndarray 类型周围的参数化包装器。