N 维数组 ( ndarray )#

ndarray 是一个(通常是固定大小的)多维容器,包含相同类型和大小的项目.数组中的维度数和项目数由其 shape 定义,这是一个由 N 个非负整数组成的 tuple ,用于指定每个维度的大小.数组中项目的类型由单独的 data-type object (dtype) 指定,其中一个与每个 ndarray 相关联.

与 Python 中的其他容器对象一样, ndarray 的内容可以通过 indexing or slicing 数组(例如,使用 N 个整数)以及通过 ndarray 的方法和属性来访问和修改.

不同的 ndarrays 可以共享相同的数据,因此在一个 ndarray 中所做的更改可能在另一个中可见.也就是说,ndarray 可以是另一个 ndarray 的“视图”,并且它引用的数据由“base”ndarray 处理.ndarrays 也可以是 Python strings 或实现 memoryviewarray 接口的对象的内存视图.

示例

一个 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

例如, slicing 可以生成数组的视图:

>>> 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] 对数组进行索引.类似的语法也用于访问 structured data type 中的字段.

参见

Array Indexing .

ndarray 的内部内存布局#

ndarray 类的实例由计算机内存的一个连续的一维段(由数组拥有,或由某个其他对象拥有)组成,以及一个将 N 个整数映射到块中项目位置的索引方案.索引可以在其中变化的范围由数组的 shape 指定.每个项目占用多少字节以及如何解释这些字节由与数组关联的 data-type object 定义.

内存段本质上是一维的,并且有许多不同的方案可以将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 . column-major 顺序(例如,在Fortran语言和Matlab中使用)和 row-major 顺序(在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顺序都是 contiguous ,即单段内存布局,其中内存块的每个部分都可以通过索引的某种组合来访问.

备注

连续数组和单段数组是同义词,并在整个文档中互换使用.

虽然具有相应标志集的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 中的数据采用 row-major (C) 顺序,但例如, basic array slicing 通常以不同的方案生成 views .

备注

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-D 迭代器.

数组接口#

__array_interface__

数组接口的Python端

__array_struct__

数组接口的C端

ctypes 外部函数接口#

ndarray.ctypes 

一个简化数组与ctypes模块交互的对象.

数组方法#

ndarray 对象有许多方法,这些方法以某种方式在数组上或与数组一起运行,通常返回一个数组结果. 这些方法在下面简要说明.(每个方法的文档字符串都有更完整的描述.)

对于以下方法,在 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 ()

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

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,则数组被视为一维数组.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])

对数组中的元素进行部分排序,使第 k 个位置上的元素的值位于排序数组中它应该在的位置.

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 的参数. 在这种情况下,

  • 如果 axis 为 None(默认值),则将数组视为 1-D 数组,并在整个数组上执行操作. 如果 self 是 0 维数组或数组标量,则此行为也是默认行为. (数组标量是类型/类 float32,float64 等的实例,而 0 维数组是精确包含一个数组标量的 ndarray 实例.)

  • 如果 axis 是一个整数,则对给定轴执行操作(对于可以沿给定轴创建的每个 1-D 子数组).

axis 参数的示例

一个大小为 3 x 3 x 3 的 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,则返回 True.

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

如果 a 的任何元素计算为 True,则返回 True.

算术,矩阵乘法和比较操作#

ndarrays 上的算术和比较操作被定义为逐元素操作,并且通常产生 ndarray 对象作为结果.

每个算术运算( + , - , * , / , // , % , divmod() , ** or pow() , << , >> , & , ^ , | , ~ )和比较运算( == , < , > , <= , >= , != )都等同于 NumPy 中相应的通用函数(或简称 ufunc ).有关更多信息,请参见 Universal Functions 部分.

比较运算符:

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,否则返回 False

备注

数组的真值测试会调用 ndarray.__bool__ ,如果数组中的元素数量不是 1,则会引发错误,因为此类数组的真值是不明确的.在这种情况下,请使用 .any().all() 来明确表达您的意图.(如果您想检查数组是否为空,请使用例如 .size > 0 .)

一元运算:

ndarray.__neg__ (/)

-self

ndarray.__pos__ (/)

+self

ndarray.__abs__ (self)

ndarray.__invert__ (/)

~self

算术运算:

ndarray.__add__ (value, /)

返回 self+value.

ndarray.__sub__ (value, /)

返回 self-value.

ndarray.__mul__ (value, /)

返回 selfvalue.

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 += 3ja = 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, /)

用于 unpickling.

基本定制:

ndarray.__new__ (args, \kwargs)

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

对于 dtype 参数,如果未给出 dtype 或它与数组的数据类型匹配,则返回对 self 的新引用.

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

返回与 self 具有相同类型的 array 视图.

容器定制:(参见 Indexing )

ndarray.__len__ (/)

返回 len(self).

ndarray.__getitem__ (key, /)

返回 self[key].

ndarray.__setitem__ (key, value, /)

将 self[key] 设置为 value.

ndarray.__contains__ (key, /)

返回 bool(key in self).

转换; 操作 int() , float()complex() . 它们仅适用于其中只有一个元素的数组,并返回适当的标量.

字符串表示:

ndarray.__str__ (/)

返回 str(self).

ndarray.__repr__ (/)

返回 repr(self).

用于 typing 的实用工具方法:

ndarray.__class_getitem__ (item, /)

返回一个围绕 ndarray 类型的参数化包装器.