N维数组 (ndarray)

ndarray 是一个(通常是固定大小的)多维的类型相同的元素数组。 数组的维度可以通过 shape 获取一个元组 tuple 包含了 N 个用于确定维度的正整数。ndarray 数组中每一个元素的的类型都是 (dtype)

和Python中的其他容器对象一样, ndarray 的内容可以通过使用 索引或切片 以及 ndarray 的属性和方法被访问和修改

不同的 ndarrays 可以共享相同的数据, 因此更改某个 ndarray 是有可能会影响到另一个 ndarray 对象的. 也就是说,某个`ndarray` 可以是另一个 ndarray视图, 它所指向的数据是由 基础 ndarray 提供的。ndarray也可以使用Python的 stringsbufferarray 内存布局

Example

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

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

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

>>> # 下面这行代码表示:x里第2行 第3列的元素,即:6
>>> x[1, 2]

下面是使用 切片 的例子

>>> y = x[:,1]
>>> y
array([2, 5])
>>> y[0] = 9 # 这也会改变x中对应的元素
>>> y
array([9, 5])
>>> x
array([[1, 9, 3],
       [4, 5, 6]])

ndarray 创建

创建新数组可以使用 Array creation routines 来构造 也可以通过使用低级 ndarray 构造函数来构造

ndarray An array object represents a multidimensional, homogeneous array of fixed-size items.

ndarray 索引

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

参见

数组索引.

ndarray 的内部内存布局

ndarray 对象由计算机内存中的一维连续区域组成,带有将每个元素映 射到内存块中某个位置的索引方案。索引可以更改的范围由数组的 shape 指定。每个元素需要多少字节以及如何解释这些字节是由与数组关联的 data-type object 对象定义的

虽然内存段本质上都是一维的,但在一维块中排列N维数组中的元素有许多不同的方案。NumPy是灵活的, ndarray 对象可以适应任何stride索引方案。使用stride索引方案时,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使用的排序方案 column-major 和C语言使用的排序方案 row-major ,只是特定 类型的stride模式,它们可以通过以下步骤处理对应的内存:

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 .

where d_j = self.shape[j].

C风格和Fortran风格的内存布局都是连续的 contiguous,其中内存块的每一部分都可以通过索引的某种组合来访问

虽然C风格和Fortran风格的连续数组(设置了相应的标志)可以用上述stride解决,但实际的情况可能有所不同。这可能发生在下面两种情况:

注解

1.如果 self.shape[k] == 1index[k] == 0 都是合法的。这意味着在偏移公式中的 n_k = 0 因此 s_k n_k = 0 对任何函数的值都有 s_k=self.strides[k]

2.如果数组没有元素( self.size == 0 )那么就没有合法的索引,也就没有可以使用的strides。任何没有元素的数组都 可以被认为是C风格和Fortran风格 的连续数组。

第1点意味着 selfself.squeeze() 始终具有相同的连续性和对齐标志值。 这也意味着,即使是高维数组也可以是C风格和Fortran风格的连续数组。

如果对所有元素的内存偏移量和自身基本偏移量是 self.itemsize 的倍数,那么数组就被认为是对齐的。

注解

默认情况下,第(1)和(2)点尚未适用。从NumPy 1.8.0开始,只有当在构建NumPy时定义了 环境变量 NPY_RELAKE_STEAS_CHAKING=1 时,它们才会一致地应用。最终,这将成为默认设置。

在生成NumPy时,可以查看 np.ones((10,1),order='C').flags.f_contiguous,如果它是 True 说明您的NumPy已经启用了松弛的stride检查

警告

对于C风格的连续数组来讲, self.strides[-1] == self.itemsize 一般不成立

对于Fortran风格的连续数组来讲 self.strides[0] == self.itemsize 一般不成立

默认情况下新的 ndarray 中的数据按 row-major 主(C)顺序排列,但是也有例外, 例如,基本数组切片 基本数组切片通常会以不同的方式生成 视图

注解

NumPy中的几种算法都适用于任意stride的数组。然而,有些算法需要 single-segment 的数组.当一个不规则stride的数组被传递到这样的算法中时,一个拷贝就会自动生成。

数组属性

数组属性反映数组本身固有的信息。通常,通过数组的属性访问它,您可以获取并设置数组的内部属性, 而无需创建新的数组。公开的属性是数组的核心部分,只有个别属性可以在不创建新数组的情况下进行有意义的重置。 每个属性的信息如下。

内存布局

下列属性用于获取数组的内存布局信息:

ndarray.flags

Notes

ndarray.shape Tuple of array dimensions.
ndarray.strides Tuple of bytes to step in each dimension when traversing an array.
ndarray.ndim Number of array dimensions.
ndarray.data Python buffer object pointing to the start of the array’s data.
ndarray.size Number of elements in the array.
ndarray.itemsize Length of one array element in bytes.
ndarray.nbytes Total bytes consumed by the elements of the array.
ndarray.base Base object if memory is from some other object.

数据类型

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

ndarray.dtype Data-type of the array’s elements.

其他属性

ndarray.T Same as self.transpose(), except that self is returned if self.ndim < 2.
ndarray.real The real part of the array.
ndarray.imag The imaginary part of the array.
ndarray.flat A 1-D iterator over the array.
ndarray.ctypes An object to simplify the interaction of the array with the ctypes module.

数组接口

参见

数组接口.

__array_interface__ Python-side of the array interface
__array_struct__ C-side of the array interface

ctypes 外部函数接口

ndarray.ctypes An object to simplify the interaction of the array with the ctypes module.

数组方法

ndarray 对象有许多方法,这些方法以某种方式对数组进行操作,通常返回数组结果。 下文简要说明这些方法,每个方法的文档都有更完整的描述:

numpy: all, any, argmax, argmin, argpartition, argsort, choose, clip, compress, copy, cumprod, cumsum, diagonal, imag, max, mean, min, nonzero, partition, prod, ptp, put, ravel, real, repeat, reshape, round, searchsorted, sort, squeeze, std, sum, swapaxes, take, trace, transpose, var.

数组转换

ndarray.item(*args) Copy an element of an array to a standard Python scalar and return it.
ndarray.tolist() Return the array as a (possibly nested) list.
ndarray.itemset(*args) Insert scalar into an array (scalar is cast to array’s dtype, if possible)
ndarray.tostring([order]) Construct Python bytes containing the raw data bytes in the array.
ndarray.tobytes([order]) Construct Python bytes containing the raw data bytes in the array.
ndarray.tofile(fid[, sep, format]) Write array to a file as text or binary (default).
ndarray.dump(file) Dump a pickle of the array to the specified file.
ndarray.dumps() Returns the pickle of the array as a string.
ndarray.astype(dtype[, order, casting, …]) Copy of the array, cast to a specified type.
ndarray.byteswap([inplace]) Swap the bytes of the array elements
ndarray.copy([order]) Return a copy of the array.
ndarray.view([dtype, type]) New view of array with the same data.
ndarray.getfield(dtype[, offset]) Returns a field of the given array as a certain type.
ndarray.setflags([write, align, uic]) Set array flags WRITEABLE, ALIGNED, (WRITEBACKIFCOPY and UPDATEIFCOPY), respectively.
ndarray.fill(value) Fill the array with a scalar value.

Shape 操作

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

ndarray.reshape(shape[, order]) Returns an array containing the same data with a new shape.
ndarray.resize(new_shape[, refcheck]) Change shape and size of array in-place.
ndarray.transpose(*axes) Returns a view of the array with axes transposed.
ndarray.swapaxes(axis1, axis2) Return a view of the array with axis1 and axis2 interchanged.
ndarray.flatten([order]) Return a copy of the array collapsed into one dimension.
ndarray.ravel([order]) Return a flattened array.
ndarray.squeeze([axis]) Remove single-dimensional entries from the shape of a.

元素的选择和操作

对于接受 axis 关键字的数组方法,默认为 None 。如果 axisNone 则将数组视为一维数组. axis 的任何其他值表示操作应该沿着该维度。

ndarray.take(indices[, axis, out, mode]) Return an array formed from the elements of a at the given indices.
ndarray.put(indices, values[, mode]) Set a.flat[n] = values[n] for all n in indices.
ndarray.repeat(repeats[, axis]) Repeat elements of an array.
ndarray.choose(choices[, out, mode]) Use an index array to construct a new array from a set of choices.
ndarray.sort([axis, kind, order]) Sort an array, in-place.
ndarray.argsort([axis, kind, order]) Returns the indices that would sort this array.
ndarray.partition(kth[, axis, kind, order]) Rearranges the elements in the array in such a way that the value of the element in kth position is in the position it would be in a sorted array.
ndarray.argpartition(kth[, axis, kind, order]) Returns the indices that would partition this array.
ndarray.searchsorted(v[, side, sorter]) Find indices where elements of v should be inserted in a to maintain order.
ndarray.nonzero() Return the indices of the elements that are non-zero.
ndarray.compress(condition[, axis, out]) Return selected slices of this array along given axis.
ndarray.diagonal([offset, axis1, axis2]) Return specified diagonals.

统计函数

许多方法都有一个名为 axis 的参数. 在这种情况下,

  • 如果 axis 的值是 None (默认值),数组被视为一维数组,并且操作是在整个数组上执行的. 如果自身是是0维数组或数组标量,则此行为也是默认行为。
  • 如果 axis 是一个整型数字, 则操作在给定的轴上完成(对于沿着给定轴创建的每个一维子数组)。.

Example of the axis argument

一个 3 x 3 x 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]])
>>> # 对于 sum 函数, axis 是它的第一个关键参数, 可以省略 *axis* , 指定值就好了,
>>> 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 指定操作(如求和)的数据类型。默认的数据类型与自身的数据类型相同。为了避免溢出,可以使用更大的数据类型来执行简化。

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

ndarray.argmax([axis, out]) Return indices of the maximum values along the given axis.
ndarray.min([axis, out, keepdims]) Return the minimum along a given axis.
ndarray.argmin([axis, out]) Return indices of the minimum values along the given axis of a.
ndarray.ptp([axis, out, keepdims]) Peak to peak (maximum - minimum) value along a given axis.
ndarray.clip([min, max, out]) Return an array whose values are limited to [min, max].
ndarray.conj() Complex-conjugate all elements.
ndarray.round([decimals, out]) Return a with each element rounded to the given number of decimals.
ndarray.trace([offset, axis1, axis2, dtype, out]) Return the sum along diagonals of the array.
ndarray.sum([axis, dtype, out, keepdims]) Return the sum of the array elements over the given axis.
ndarray.cumsum([axis, dtype, out]) Return the cumulative sum of the elements along the given axis.
ndarray.mean([axis, dtype, out, keepdims]) Returns the average of the array elements along given axis.
ndarray.var([axis, dtype, out, ddof, keepdims]) Returns the variance of the array elements, along given axis.
ndarray.std([axis, dtype, out, ddof, keepdims]) Returns the standard deviation of the array elements along given axis.
ndarray.prod([axis, dtype, out, keepdims]) Return the product of the array elements over the given axis
ndarray.cumprod([axis, dtype, out]) Return the cumulative product of the elements along the given axis.
ndarray.all([axis, out, keepdims]) Returns True if all elements evaluate to True.
ndarray.any([axis, out, keepdims]) Returns True if any of the elements of a evaluate to True.

四则运算、 矩阵运算、 比较操作

ndarrays 的算术和比较操作被定义为元素级操作, 通常产生 ndarrays 对象作为结果。

每一个算术运算符 (+, -, *, /, //, %, divmod(), ** or pow(), <<, >>, &, ^, |, ~) 和比较运算符 (==, <, >,``<=``, >=, !=) 等效于 NumPy中相应的通用函数 universal function ( ufunc) 查看更多信息 Universal Functions.

Comparison operators:

ndarray.__lt__ x.__lt__(y) <==> x<y
ndarray.__le__ x.__le__(y) <==> x<=y
ndarray.__gt__ x.__gt__(y) <==> x>y
ndarray.__ge__ x.__ge__(y) <==> x>=y
ndarray.__eq__ x.__eq__(y) <==> x==y
ndarray.__ne__ x.__ne__(y) <==> x!=y

数组中的真实值 (bool):

ndarray.__nonzero__ x.__nonzero__() <==> x != 0

注解

数组的真值测试调用 ndarray.__nonzero__,如果数组中的元素数大于1,则会引发错误, 因为此类数组的真值是模糊的。使用 .any().all() 来明确在这种情况 下意味着什么。(如果元素数为0,则数组的计算结果为 False )

ndarray.__neg__ x.__neg__() <==> -x
ndarray.__pos__ x.__pos__() <==> +x
ndarray.__abs__() <==> abs(x)
ndarray.__invert__ x.__invert__() <==> ~x
ndarray.__add__ x.__add__(y) <==> x+y
ndarray.__sub__ x.__sub__(y) <==> x-y
ndarray.__mul__ x.__mul__(y) <==> x*y
ndarray.__div__ x.__div__(y) <==> x/y
ndarray.__truediv__ x.__truediv__(y) <==> x/y
ndarray.__floordiv__ x.__floordiv__(y) <==> x//y
ndarray.__mod__ x.__mod__(y) <==> x%y
ndarray.__divmod__(y) <==> divmod(x, y)
ndarray.__pow__(y[, z]) <==> pow(x, y[, z])
ndarray.__lshift__ x.__lshift__(y) <==> x<<y
ndarray.__rshift__ x.__rshift__(y) <==> x>>y
ndarray.__and__ x.__and__(y) <==> x&y
ndarray.__or__ x.__or__(y) <==> x|y
ndarray.__xor__ x.__xor__(y) <==> x^y

注解

  • pow 的任何第三个参数都会被忽略,因为底层的 ufunc 只接受两个参数。
  • 三个除法运算符都是定义好的,默认使用的是 div。但当 __future__ 生效时使用 truediv
  • 因为 ndarray 是一种内置类型(用C编写),所以没有直接定义 __r{op}__ 特殊方法
  • 可以使用 set_numeric_ops 修改数组的方法调用,可以实现许多特殊的算法
ndarray.__iadd__ x.__iadd__(y) <==> x+=y
ndarray.__isub__ x.__isub__(y) <==> x-=y
ndarray.__imul__ x.__imul__(y) <==> x*=y
ndarray.__idiv__ x.__idiv__(y) <==> x/=y
ndarray.__itruediv__ x.__itruediv__(y) <==> x/=y
ndarray.__ifloordiv__ x.__ifloordiv__(y) <==> x//=y
ndarray.__imod__ x.__imod__(y) <==> x%=y
ndarray.__ipow__ x.__ipow__(y) <==> x**=y
ndarray.__ilshift__ x.__ilshift__(y) <==> x<<=y
ndarray.__irshift__ x.__irshift__(y) <==> x>>=y
ndarray.__iand__ x.__iand__(y) <==> x&=y
ndarray.__ior__ x.__ior__(y) <==> x|=y
ndarray.__ixor__ x.__ixor__(y) <==> x^=y

警告

这些运算由两个操作数的数据类型确定的精度来执行计算,但会默认向下转换结果(如果需要),以便将结果放回数组中。 因此对于混合精度计算 A {op}= B 可能与 A = A {op} B 不同。

矩阵运算:

ndarray.__matmul__

注解

在Python 3.5中,在PEP 465之后引入了矩阵运算符 @@=。出于测试目的,NumPy 1.10.0有 @ 的初步实现。 更多的文档可以在 matmul 文档中找到

特殊方法

用于标准库函数:

ndarray.__copy__() Used if copy.copy is called on an array.
ndarray.__deepcopy__(memo, /) Used if copy.deepcopy is called on an array.
ndarray.__reduce__() For pickling.
ndarray.__setstate__(state, /) For unpickling.

基本定制:

ndarray.__new__(S, …)
ndarray.__array__(|dtype) Returns either a new reference to self if dtype is not given or a new array of provided data type if dtype is different from the current dtype of the array.
ndarray.__array_wrap__(obj)

容器定制: (see Indexing)

ndarray.__len__() <==> len(x)
ndarray.__getitem__ x.__getitem__(y) <==> x[y]
ndarray.__setitem__ x.__setitem__(i, y) <==> x[i]=y
ndarray.__contains__ x.__contains__(y) <==> y in x

转换操作:complexintlongfloat()`和:func:`oct。 它们只处理包含一个元素并返回适当标量的数组

ndarray.__int__() <==> int(x)
ndarray.__long__() <==> long(x)
ndarray.__float__() <==> float(x)
ndarray.__oct__() <==> oct(x)
ndarray.__hex__() <==> hex(x)

字符串表示:

ndarray.__str__() <==> str(x)
ndarray.__repr__() <==> repr(x)