N维数组 (ndarray
)#
一个 ndarray
是一个(通常是固定大小的)多维容器,其中包含相同类型和大小的项。数组的维度和项数由其 shape
定义,shape
是一个由 N 个非负整数组成的 tuple
,指定了每个维度的大小。数组中项的类型由一个独立的 数据类型对象 (dtype) 指定,每个 ndarray 都关联着一个。
与 Python 中的其他容器对象一样,ndarray
的内容可以通过对数组进行 索引或切片(例如,使用 N 个整数),以及通过 ndarray
的方法和属性来访问和修改。
不同的 ndarrays
可以共享相同的数据,因此在一个 ndarray
中所做的更改可能会在另一个中可见。也就是说,一个 ndarray 可以是另一个 ndarray 的“视图”,它所引用的数据由“基础”ndarray 管理。ndarray 也可以是 Python strings
或实现 memoryview
或 array 接口的对象的内存视图。
示例
一个 2x3 的二维数组,由 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
构造函数来构建新数组
|
数组对象表示一个多维的、同构的固定大小项的数组。 |
索引数组#
数组可以使用扩展的 Python 切片语法 array[selection]
进行索引。类似的语法也用于访问 结构化数据类型 中的字段。
另请参阅
数组索引.
ndarray 的内部内存布局#
ndarray
类的一个实例包含一个连续的一维计算机内存段(由数组或其他对象拥有),并结合一个索引方案,该方案将 N 个整数映射到该块中项的位置。索引可变动的范围由数组的 shape
指定。每个项占用多少字节以及这些字节如何解释由与数组关联的 数据类型对象 定义。
内存段本质上是一维的,并且有许多不同的方案用于将 N 维数组的项排列成一维块。NumPy 具有灵活性,ndarray
对象可以适应任何*步幅索引方案*。在步幅方案中,N 维索引 \((n_0, n_1, ..., n_{N-1})\) 对应于从与数组关联的内存块开头起的偏移量(以字节为单位)
其中 \(s_k\) 是指定数组 strides
的整数。列主序(例如,在 Fortran 语言和 Matlab 中使用)和 行主序(在 C 中使用)方案只是步幅方案的特定类型,对应于可以通过步幅*寻址*的内存
其中 \(d_j\) = self.shape[j]。
C 和 Fortran 两种顺序都是 连续的,即单段内存布局,其中内存块的每个部分都可以通过索引的某种组合来访问。
注意
*连续数组* 和 *单段数组* 是同义词,在整个文档中可互换使用。
虽然设置了相应标志的 C 风格和 Fortran 风格连续数组可以使用上述步幅进行寻址,但实际步幅可能不同。这可能发生在两种情况下
如果
self.shape[k] == 1
,则对于任何合法的索引index[k] == 0
。这意味着在偏移量公式中 \(n_k = 0\),因此 \(s_k n_k = 0\),而 \(s_k\) = self.strides[k] 的值是任意的。如果数组没有元素(
self.size == 0
),则没有合法索引,步幅也从不使用。任何没有元素的数组都可以被视为 C 风格和 Fortran 风格连续的。
第 1 点意味着 self
和 self.squeeze()
总是具有相同的连续性和 aligned
标志值。这也意味着即使是高维数组也可以同时是 C 风格和 Fortran 风格连续的。
如果所有元素的内存偏移量和基偏移量本身是 self.itemsize
的倍数,则数组被认为是对齐的。理解*内存对齐*可以在大多数硬件上带来更好的性能。
警告
通常情况下,对于 C 风格连续数组,self.strides[-1] == self.itemsize
并不成立,对于 Fortran 风格连续数组,self.strides[0] == self.itemsize
也不成立。
除非另有说明,新 ndarrays
中的数据以 行主序 (C) 存储,但例如 基本数组切片 通常会以不同的方案生成 视图。
注意
NumPy 中的几种算法适用于任意步幅的数组。然而,某些算法需要单段数组。当不规则步幅的数组传递给此类算法时,会自动创建一份副本。
数组属性#
数组属性反映了数组本身的固有信息。通常,通过其属性访问数组可以获取并有时设置数组的固有属性,而无需创建新数组。公开的属性是数组的核心部分,其中只有一部分可以有意义地重置而无需创建新数组。下面提供了每个属性的信息。
内存布局#
以下属性包含有关数组内存布局的信息
有关数组内存布局的信息。 |
|
数组维度的元组。 |
|
遍历数组时,每个维度要步进的字节元组。 |
|
数组维度数。 |
|
指向数组数据开头的 Python 缓冲区对象。 |
|
数组中的元素数量。 |
|
一个数组元素的字节长度。 |
|
数组元素消耗的总字节数。 |
|
如果内存来自其他对象,则为基对象。 |
数据类型#
另请参阅
与数组关联的数据类型对象可以在 dtype
属性中找到
数组元素的数据类型。 |
其他属性#
转置数组的视图。 |
|
数组的实部。 |
|
数组的虚部。 |
|
数组上的一维迭代器。 |
数组接口#
另请参阅
数组接口的 Python 侧 |
|
数组接口的 C 侧 |
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
。
数组转换#
|
将数组的一个元素复制到标准 Python 标量并返回。 |
将数组返回为 |
|
|
构造包含数组原始数据字节的 Python 字节串。 |
|
将数组写入文件作为文本或二进制(默认)。 |
|
将数组的 pickle 转储到指定文件。 |
将数组的 pickle 返回为字符串。 |
|
|
数组的副本,转换为指定类型。 |
|
交换数组元素的字节 |
|
返回数组的副本。 |
|
具有相同数据的新数组视图。 |
|
将给定数组的字段作为特定类型返回。 |
|
分别设置数组标志 WRITEABLE, ALIGNED, WRITEBACKIFCOPY。 |
|
用标量值填充数组。 |
形状操作#
对于 reshape、resize 和 transpose,单个元组参数可以替换为 n
个整数,这些整数将被解释为 n 元组。
|
返回包含相同数据但具有新形状的数组。 |
|
就地改变数组的形状和大小。 |
|
返回轴已转置的数组视图。 |
|
返回轴 axis1 和 axis2 互换的数组视图。 |
|
返回折叠成一维的数组副本。 |
|
返回一个扁平化的数组。 |
|
从 a 中删除长度为一的轴。 |
项选择和操作#
对于接受 *axis* 关键字参数的数组方法,它默认为 *None*。如果 *axis* 是 *None*,则数组被视为一维数组,并在整个数组上执行操作。如果 self 是 0 维数组或数组标量(数组标量是 float32、float64 等类型/类的实例,而 0 维数组是恰好包含一个数组标量的 ndarray 实例),这也是默认行为。
|
返回从给定索引处 a 的元素形成的数组。 |
|
对于索引中的所有 n,设置 |
|
重复数组的元素。 |
|
使用索引数组从一组选择中构造一个新数组。 |
|
就地排序数组。 |
|
返回将排序此数组的索引。 |
|
部分排序数组中的元素,使得第 k 个位置的元素值处于其在已排序数组中的位置。 |
|
返回将分区此数组的索引。 |
|
查找应将 v 的元素插入到 a 中以保持顺序的索引。 |
返回非零元素的索引。 |
|
|
返回沿给定轴的此数组的选定切片。 |
|
返回指定的对角线。 |
计算#
许多这些方法都接受一个名为 *axis* 的参数。在这种情况下,
如果 *axis* 是 *None*(默认),则数组被视为一维数组,并在整个数组上执行操作。如果 self 是 0 维数组或数组标量,此行为也是默认行为。(数组标量是 float32、float64 等类型/类的实例,而 0 维数组是恰好包含一个数组标量的 ndarray 实例。)
如果 *axis* 是一个整数,则操作在给定轴上执行(对于沿给定轴可以创建的每个一维子数组)。
*axis* 参数的示例
一个 3x3x3 的三维数组,对其三个轴分别求和
>>> 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
并具有相同的元素数量。它可以具有不同的数据类型,在这种情况下将执行类型转换。
|
返回沿给定轴的最大值。 |
|
返回沿给定轴的最大值的索引。 |
|
返回沿给定轴的最小值。 |
|
返回沿给定轴的最小值的索引。 |
|
返回其值被限制在 |
所有元素的复共轭。 |
|
|
返回 a,其中每个元素都四舍五入到给定的小数位数。 |
|
返回数组对角线上的和。 |
|
返回数组元素沿给定轴的和。 |
|
返回元素沿给定轴的累积和。 |
|
返回数组元素沿给定轴的平均值。 |
|
返回数组元素沿给定轴的方差。 |
|
返回数组元素沿给定轴的标准差。 |
|
返回数组元素沿给定轴的乘积 |
|
返回元素沿给定轴的累积乘积。 |
|
如果所有元素都评估为 True,则返回 True。 |
|
如果 a 的任何元素评估为 True,则返回 True。 |
算术、矩阵乘法和比较操作#
对 ndarrays
的算术和比较操作定义为元素级操作,通常产生 ndarray
对象作为结果。
每个算术操作(+
、-
、*
、/
、//
、%
、divmod()
、**
或 pow()
、<<
、>>
、&
、^
、|
、~
)和比较操作(==
、<
、>
、<=
、>=
、!=
)都等同于 NumPy 中相应的通用函数(简称 ufunc)。有关更多信息,请参见 通用函数 一节。
比较运算符
|
返回 self<value。 |
|
返回 self<=value。 |
|
返回 self>value。 |
|
返回 self>=value。 |
|
返回 self==value。 |
|
返回 self!=value。 |
数组的真值(bool()
)
如果 self 为 True 则返回 True,否则返回 False |
注意
数组的真值测试调用 ndarray.__bool__
,如果数组中的元素数量不为 1,则会引发错误,因为此类数组的真值是模糊的。在这种情况下,请改用 .any()
和 .all()
以明确其含义。(如果您想检查数组是否为空,例如使用 .size > 0
。)
一元操作
-self |
|
+self |
|
|
|
~self |
算术
|
返回 self+value。 |
|
返回 self-value。 |
|
返回 self*value。 |
|
返回 self/value。 |
|
返回 self//value。 |
|
返回 self%value。 |
|
返回 divmod(self, value)。 |
|
返回 pow(self, value, mod)。 |
|
返回 self<<value。 |
|
返回 self>>value。 |
|
返回 self&value。 |
|
返回 self|value。 |
|
返回 self^value。 |
注意
由于
ndarray
是一个内置类型(用 C 编写),因此__r{op}__
特殊方法没有直接定义。用于实现数组许多算术特殊方法的函数可以使用
__array_ufunc__
进行修改。
算术,就地操作
|
返回 self+=value。 |
|
返回 self-=value。 |
|
返回 self*=value。 |
|
返回 self/=value。 |
|
返回 self//=value。 |
|
返回 self%=value。 |
|
返回 self**=value。 |
|
返回 self<<=value。 |
|
返回 self>>=value。 |
|
返回 self&=value。 |
|
返回 self|=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
重新绑定到结果。
矩阵乘法
|
返回 self@value。 |
特殊方法#
用于标准库函数
当在数组上调用 |
|
|
当在数组上调用 |
用于 pickle 序列化。 |
|
|
用于 unpickle 反序列化。 |
基本定制
|
|
|
如果未给定 |
|
返回 |
容器定制:(参见 索引)
返回 len(self)。 |
|
|
返回 self[key]。 |
|
将 self[key] 设置为 value。 |
|
返回 key 是否在 self 中。 |
转换;操作 int()
、float()
和 complex()
。它们仅适用于包含一个元素的数组,并返回相应的标量。
|
|
|
|
字符串表示
返回 str(self)。 |
|
返回 repr(self)。 |
类型化实用方法
|
返回围绕 |