基础
NumPy的主要对象是同质多维数组。它是一张表,所有元素(通常是数字)的类型都相同,并通过正整数元组索引。在NumPy中,维度称为轴。轴的数目为秩rank。
例如,3D空间中的点的坐标[1, 2, 1]是rank为1的数组,因为它具有一个轴。该轴的长度为3。在下图所示的示例中,数组的rank为2(它是2维的)。第一维度(轴)的长度为2,第二维度的长度为3。
NumPy的数组的类称为ndarray。别名为array。请注意,numpy.array与标准Python库的类array.array不同,后者仅处理一维数组并提供较少的功能。ndarray对象的更重要的属性是:
-
ndarray.ndim
- 数组的轴(维度)的个数。 在Python世界中,维度的数量被称为rank。 ndarray.shape
-
数组的维度。
这是一个整数的元组,表示每个维度中数组的大小。
对于具有n行和m列的矩阵,
shape将是(n,m)。 因此,shape元组的长度就是rank或维度的个数ndim。
ndarray.size
-
数组元素的总数。
这等于
shape的元素的乘积。
ndarray.dtype
- 描述数组中元素类型的对象。 可以使用标准Python类型创建或指定dtype。 另外NumPy提供了自己的类型。 例如numpy.int32、numpy.int16和numpy.float64。 ndarray.itemsize
-
数组中每个元素的字节大小。
例如,元素为
float64类型的数组的itemsize为8(=64/8),而complex32类型的数组的comitemsize为4(=32/8)。 它等于ndarray.dtype.itemsize。
ndarray.data
- 该缓冲区包含数组的实际元素。 通常,我们不需要使用此属性,因为我们将使用索引访问数组中的元素。
示例
数组创建
有几种方法来创建数组。
例如,你可以使用array函数从常规Python列表或元组中创建数组。得到的数组的类型从序列中元素的类型推导出。
常见的错误在于用多个数字参数调用array,而不是提供单个数字列表作为参数。
array将序列的序列转换成二维阵列,将序列的序列的序列转换成三维数组,等等。
数组的类型也可以在创建时明确指定:
通常,数组的元素最初是未知的,但其大小是已知的。因此,NumPy提供了几个函数来创建具有初始占位符内容的数组。这些最小化数组增长的必要,数组增长是一种昂贵的操作。
函数zeros创建一个由0组成的数组,函数ones创建一个由1数组的数组,函数empty内容是随机的并且取决于存储器的状态。默认情况下,创建的数组的dtype为float64。
为了创建数字序列,NumPy提供类似于range的函数,返回数组而不是列表。
当arange与浮点参数一起使用时,由于浮点数的精度是有限的,通常不可能预测获得的元素数量。出于这个原因,通常最好使用函数linspace,它接收我们想要的元素数量而不是步长作为参数:
打印数组
当打印数组时,NumPy以类似于嵌套列表的方式显示它,但是使用以下布局:
- 最后一个轴从左到右打印,
- 第二个到最后一个从上到下打印,
- 其余的也从上到下打印,每个切片与下一个用空行分开。
一维数组被打印为行、二维为矩阵和三维为矩阵列表。
有关reshape的详情,请参阅下文。
如果数组太大而无法打印,NumPy会自动跳过数组的中心部分,并只打印边角:
要禁用此行为并强制NumPy打印整个数组,你可以使用set_printoptions更改打印选项。
基本操作
数组上的算术运算符使用元素级别。将创建一个新数组并用结果填充。
与许多矩阵语言不同,乘法运算符*的运算在NumPy数组中是元素级别的。可以使用dot函数或方法执行矩阵乘积:
某些操作(如+=和*=)可以修改现有数组,而不是创建新数组。
当使用不同类型的数组操作时,结果数组的类型对应于更一般或更精确的数组(称为向上转换的行为)。
许多一元操作,例如计算数组中所有元素的和,被实现为ndarray类的方法。
默认情况下,这些操作适用于数组,就像它是一个数字列表,而不管其形状。但是,通过指定axis参数,你可以沿着数组的指定轴应用操作:
通用函数
NumPy提供了熟悉的数学函数,如sin,cos和exp。在NumPy中,这些被称为“通用函数”(ufunc)。在NumPy中,这些函数在数组上按元素级别操作,产生一个数组作为输出。
另见
all, any, apply_along_axis, argmax, argmin, argsort, average, bincount, ceil, clip, conj, corrcoef, cov, cross, cumprod, cumsum, diff, dot, floor,inner, inv, lexsort, max, maximum, mean, median, min, minimum, nonzero, outer, prod, re, round, sort, std, sum, trace, transpose, var, vdot,vectorize, where
索引、切片和迭代
一维数组可以索引,切片和迭代,非常类似于列表和其他Python序列。
多维数组每个轴可以有一个索引。这些索引以逗号分隔的元组给出:
当提供比轴数更少的索引时,缺失的索引被认为是一个完整切片:
b[i]方括号中的表达式i被视为后面紧跟着:的多个实例,用于表示剩余轴。NumPy也允许你使用三个点写为b[i,...]。
三个点(...)表示产生完整索引元组所需的冒号。例如,如果x是rank为的5数组(即,它具有5个轴),则
x[1,2,...]等效于x[1,2,:,:,:]x[...,3]到x[:,:,:,:,3]x[4,...,5,:]到x[4,:,:,5,:]
对多维数组的迭代是相对于第一个轴完成的:
但是,如果想对数组中的每个元素执行一个操作,可以使用flat属性,它是一个迭代器
另见
形状操作
更改数组的形状
数组具有由沿着每个轴的元素数量给出的形状:
可以使用各种命令更改数组的形状。请注意,以下三个命令都返回修改的数组,但不更改原始数组:
由ravel()产生的数组中元素的顺序通常是“C风格”,也就是说,最右边的索引“改变最快”,所以[0,0]之后的元素是[0,1] 。如果数组被重塑成某种其他形状,则该数组也被视为“C风格”。NumPy通常创建按此顺序存储的数组,因此ravel()通常不需要复制其参数,但如果数组是通过对另一个数组进行切片或使用不寻常的选项创建的,则可能需要复制。还可以使用可选参数来指示函数ravel()和reshape(),以使用FORTRAN式数组,其中最左侧的索引改变最快。
reshape函数返回其修改形状的参数,而ndarray.resize方法修改数组本身:
如果在reshape操作中将维度指定为-1,则会自动计算其他维度:
将不同数组堆叠在一起
几个数组可以沿不同的轴堆叠在一起:
函数column_stack将1D数组作为列堆叠到2D数组中。它等同于仅用于2D数组的hstack:
另一方面,对于任何输入数组,函数row_stack等效于vstack。一般来说,对于具有两个以上维度的数组,hstack沿第二轴堆叠,vstack沿第一轴堆叠,concatenate允许一个可选参数,给出串接应该发生的轴。
注意
在复杂情况下,r_和c_可用于通过沿一个轴堆叠数字来创建数组。它们允许使用范围文字(“:”)
当以数组作为参数使用时,r_和c_类似于其默认行为中的vstack和hstack,但是允许一个可选参数给出要沿其连接的轴的编号。
将一个数组分成几个较小的数组
使用hsplit,可以沿其水平轴拆分数组,通过指定要返回的均匀划分的数组数量,或通过指定要在其后进行划分的列:
vsplit沿垂直轴分割,array_split允许指定沿哪个轴分割。
复制和视图
当计算和操作数组时,它们的数据有时被复制到新的数组中,有时不复制。这通常是初学者的混乱的来源。有三种情况:
完全不复制
简单赋值不会创建数组对象或其数据的拷贝。
Python将可变对象作为引用传递,因此函数调用不会复制。
视图或浅复制
不同的数组对象可以共享相同的数据。view方法创建一个新数组对象,该对象看到相同的数据。
对数组切片返回一个视图:
深复制
copy方法生成数组及其数据的完整拷贝。
函数和方法概述
这里是一些有用的NumPy函数和方法名称按类别排序的列表。有关完整列表,请参见Routines。
-
数组创建
-
arange,array,copy,empty,empty_like,eye,fromfile,fromfunction,identity,linspace,logspace,mgrid,ogrid,ones,ones_like, r,zeros,zeros_like
转换
-
ndarray.astype,atleast_1d,atleast_2d,atleast_3d,mat
操纵
-
array_split,column_stack,concatenate,diagonal,dsplit,dstack,hsplit,hstack,ndarray.item,newaxis,ravel,repeat,reshape,resize,squeeze,swapaxes,take,transpose,vsplit,vstack
问题
-
all,any,nonzero,where
顺序
-
argmax,argmin,argsort,max,min,ptp,searchsorted,sort
操作
-
choose,compress,cumprod,cumsum,inner,ndarray.fill,imag,prod,put,putmask,real,sum
基本统计
-
cov,mean,std,var
基本线性代数
-
cross,dot,outer,linalg.svd,vdot
Less Basic
Broadcasting规则
Broadcasting允许通用函数以有意义的方式处理具有不完全相同形状的输入。
Broadcasting的第一个规则是,如果所有输入数组不具有相同数量的维度,则“1”将被重复地添加到较小数组的形状,直到所有数组具有相同数量的维度。
Broadcasting的第二个规则确保沿着特定维度具有大小为1的数组表现得好像它们具有沿着该维度具有最大形状的数组的大小。假定数组元素的值沿“Broadcasting”数组的该维度相同。
应用广播规则后,所有数组的大小必须匹配。有关详细信息,请参见Broadcasting。
花式索引和索引技巧
NumPy提供了比常规Python序列更多的索引能力。除了通过整数和切片索引之外,如前所述,数组可以由整数数组和布尔数组索引。
使用索引数组索引
当被索引的数组a是多维的时候,单个索引数组指的是a的第一个维度。以下示例通过使用调色板将标签的图像转换为彩色图像来显示此行为。
我们还可以为多个维度提供索引。每个维度的索引数组必须具有相同的形状。
当然,我们可以把i和j放在一个序列中(比如一个列表),然后用列表做索引。
但是,我们不能将i和j放入一个数组中,因为这个数组将被解释为索引第一个维度。
另一个常见的使用数组索引的方法是搜索时间相关系列的最大值:
你还可以使用数组索引作为目标来赋值:
但是,当索引列表包含重复时,赋值完成多次,留下最后一个值:
这是足够合理的,但如果你想使用Python的+=构造要小心,因为它可能不会做你想要的:
即使0在索引列表中出现两次,第0个元素也只增加一次。这是因为Python要求“a + = 1”等同于“a = a + 1”。
使用布尔数组索引
当我们用(整数)索引数组索引数组时,我们提供要选取的索引列表。使用布尔索引,方法是不同的;我们明确地选择数组中的哪些元素我们想要的,哪些不是。
对于布尔索引,最自然的方法是使用与原始数组具有相同形状的布尔数组:
此属性在赋值时非常有用:
你可以查看以下示例,了解如何使用布尔索引生成Mandelbrot集的图像:
使用布尔索引的第二种方法更类似于整数索引;对于数组的每个维度,我们给出一个1D布尔数组,选择我们想要的切片:
请注意,1D布尔数组的长度必须与你要切片的维度(或轴)的长度一致。在前面的示例中,b1是rank为1的数组,其长度为3(a中行的数量),b2(长度4)适合于索引a的第二个rank(列)。
ix_()函数
ix_函数可以用于组合不同的向量,以便获得每个n-uplet的结果。例如,如果要计算从向量a、b和c中的取得的所有三元组的所有a + b * c:
你还可以如下实现reduce:
然后将其用作:
与正常的ufunc.reduce相比,这个版本的reduce的优点是它使用Broadcasting规则,以避免创建参数数组输出的大小乘以向量的数量。
使用字符串索引
请参见结构化数组。
线性代数
继续工作。这里包括基本线性代数。
简单数组操作
有关更多信息,请参阅numpy目录中的linalg.py。
技巧和提示
这里我们给出一个简短有用的提示。
“自动”Reshape
要更改数组的大小,你可以省略其中一个size,它将被自动推导出来:
向量堆叠
我们如何从等大小的行向量列表中构造一个二维数组?在MATLAB中这是很容易的:如果x和y是两个相同长度的向量,你只需要m=[x;y] 。在NumPy中,这通过函数column_stack,dstack,hstack和vstack工作,具体取决于要做什么堆叠。例如:
这些函数背后的逻辑在两个维度可能很奇怪。
本文介绍了NumPy的基础概念,包括数组的创建、操作及索引方式。涵盖了数组的属性、数组的算术运算、索引、切片和迭代等内容。
1598

被折叠的 条评论
为什么被折叠?



