ndarray
ndarray
比较重要的属性有:
ndarray.ndim
:ndarray
的rank
,即有几个维度ndarray.shape
:dimensions of the array
。它是N
个正整数组成的元组,用于指示容器每一个维度的大小。对于一个n
行m
列的矩阵,.shape
为(n,m)
。因此.shape
的length
等于ndarray.ndim
ndarray.size
:ndarray
中elements
的总数量。它等于.shape
中各分量的乘积ndarray.dtype
:一个object
用于描述array
中elements
的type
。你可以创建标准的
Python type
,也可以用Numpy
提供的type
,如numpy.int32
、numpy.float64
等ndarray.itemsize
:array
中每个element
的字节大小。它也等于ndarray.dtype.itemsize
ndarray.data
:存放真正数据的buffer
。通常我们不会使用这个属性,因为我们从不通过这个属性来访问数据。通常都是用索引来访问数据
ndarray.real
:返回ndarray
的实部ndarrray.imag
:返回ndarray
的虚部ndarray.flat
:返回ndarray
上的一个一维的iterator
ndarray.T
:返回ndarray
的转置。如果ndarray
维度小于 1,则返回它本身
如果每一行的列数不是完全相同,那么
.shape
属性只会显示(rows,)
这种格式。
1. 创建 ndarray
创建 ndarray
对象有很多方法:
a. 创建全 1 或者全 0
empty(shape[,type,order])
:返回一个新的ndarray
,指定了shape
和type
,但是没有初始化元素。 因此其内容是随机的。empty_like(a[,type,order,subok])
:返回一个新的ndarray
,shape
与a
相同,但是没有初始化元素。因此其内容是随机的。eye(N[, M, k, dtype])
:返回一个二维矩阵,对角线元素为 1,其余元素为 0。M
默认等于N
。k
默认为 0 表示对角线元素为 1,如为正数则表示对角线上方一格的元素为 1,如为负数表示对角线下方一格的元素为 1.identity(n[, dtype])
:返回一个单位矩阵ones(shape[, dtype, order])
:返回一个新的ndarray
,指定了shape
和type
,每个元素初始化为 1. -ones_like(a[, dtype, order, subok])
:返回一个新的ndarray
,shape
与a
相同,每个元素初始化为 1。zeros(shape[, dtype, order])
:返回一个新的ndarray
,指定了shape
和type
,每个元素初始化为 0.zeros_like(a[, dtype, order, subok])
:返回一个新的ndarray
,shape
与a
相同,每个元素初始化为 0。full(shape, fill_value[, dtype, order])
:返回一个新的ndarray
,指定了shape
和type
, 每个元素初始化为fill_value
。full_like(a, fill_value[, dtype, order, subok])
:返回一个新的ndarray
,shape
与a
相同,每个元素初始化为fill_value
。
这里有几个共同的参数:
a
:一个array-like
类型的实例,它不一定是ndarray
,可以为list
、tuple
、list of tuple
、list of list
、tuple of list
、tuple of tuple
等等。dtype
:结果的元素的类型,默认为float
。你可以指定Python
的标准数值类型,也可以使用numpy
的数值类型如:numpy.int32
或者numpy.float64
等等。order
:指定存储多维数据的方式。可以为'C'
,表示按行优先存储(C 风格);可以为'F'
,表示按列优先存储(Fortran 风格)对于
**_like()
函数,order
可以为:'C'
,'F'
,'A'
(表示结果的order
与a
相同),'K'
(表示结果的order
与a
尽可能)subok
:bool
值,如果为True
则如果a
为ndarray
的子类(如matrix
类),则结果类型与ndarray
类型相同。如果为False
则结果类型始终为ndarray
。默认为True
。
b. 从现有数据创建
array(object[, dtype, copy, order, subok, ndmin])
:从object
创建。object
可以是一个ndarray
,也可以是一个array_like
的对象, 也可以是一个含有返回一个序列或者ndarray
的__array__
方法的对象,或者一个序列。copy
:默认为True
,表示拷贝对象order
可以为'C'、'F'、'A'
。默认为'A'
。subok
默认为False
ndmin
:指定结果ndarray
最少有多少个维度。
asarray(a[, dtype, order])
:将a
转换成一个ndarray
。其中a
是array_like
的对象, 可以是list
、list of tuple
、tuple
、tuple of list
、ndarray
类型。order
默认为C
。asanyarray(a[, dtype, order])
:将a
转换成ndarray
。ascontiguousarray(a[, dtype])
:返回 C 风格的连续ndarray
asmatrix(data[, dtype])
:返回matrix
copy(a[, order])
:返回ndarray
,从输入中拷贝元素frombuffer(buffer[, dtype, count, offset])
:从输入数据中返回一维ndarray
。count
指定读取的数量,-1
表示全部读取;offset
指定从哪里开始读取,默认为 0fromfile(file[, dtype, count, sep])
:从二进制文件或者文本文件中读取数据返回ndarray
.sep
:当从文本文件中读取时,数值之间的分隔字符串,如果sep
是空字符串则表示文件应该作为二进制文件读取;如果sep
为" "
表示可以匹配 0 个或者多个空白字符。fromfunction(function, shape, **kwargs)
:返回一个ndarray
。从函数中获取每一个坐标点的数据。假设shape
的rank
为 N,那么function
带有N
个参数,fn(x1,x2,...x_N)
,其返回值就是该坐标点的值。fromiter(iterable, dtype[, count])
:从可迭代对象中迭代获取数据创建一维ndarray
。fromstring(string[, dtype, count, sep])
:从字符串或者raw binary
中创建一维ndarray
。如果sep
为空字符串则string
将按照二进制数据解释(即每个字符作为ASCII
码值对待)。loadtxt(fname[, dtype, comments, delimiter, ...])
:从文本文件中加载数据创建ndarray
,要求文本文件每一行都有相同数量的数值。comments
:指示注释行的起始字符,可以为单个字符或者字符列表(默认为#
).delimiter
:指定数值之间的分隔字符串,默认为空白符。converters
:将指定列号(0,1,2...) 的列数据执行转换,是一个map
,如{0:func1}
表示对第一列数据执行func1(val_0)
。skiprows
:指定跳过开头的多少行。usecols
:指定读取那些列(0 表示第一列)。
c. 从数值区间创建
arange([start,] stop[, step,][, dtype])
:返回均匀间隔的值组成的一维ndarray
。区间是半闭半开的[start,stop)
,其采样行为类似 Python 的range
函数。start
为开始点,stop
为终止点,setp
为步长,默认为 1。这几个数可以为整数可以为浮点数。注意如果setp
为浮点数,则结果可能有误差,因为浮点数相等比较不准确。linspace(start, stop[, num, endpoint, ...])
:返回num
个均匀采样的数值组成的一维ndarray
(默认为 50)。区间是比区间[start,stop]
。endpoint
为布尔值,如果为真则表示stop
是最后采样的值(默认为True
),否则结果不包含stop
。retstep
如果为True
则返回结果包含采样步长step
,默认为True
。logspace(start, stop[, num, endpoint, base, ...])
:返回对数级别上均匀采样的数值组成的一维ndarray
。采样点开始于base^start
,结束于base&stop
。base
为对数的基。它逻辑上相当于先执行
arange
获取数组array
,然后再执行base^array[i]
获取采样点
2. 打印 ndarray
当打印 ndarray
时, numpy
按照 Python 的嵌套 list
的格式打印输出,但是按照以下顺序打印:
- 最底层的
axis
按照从左到右的顺序输出 - 次底层的
axis
按照从上到下的顺序输出 - 其他层的
axis
也是按照从上到下的顺序输出,但是每个slice
中间间隔一条空行
如: 一维的 ndarray
按行打印;二维的 ndarray
按照矩阵打印;三维的 ndarray
按照矩阵的 list
打印
如果 ndarray
太大,那么 numpy
默认跳过中间部分的数据而只是输出四个角落的数据。
要想任何时候都打印全部数据,可以在
print(array)
之前设置选项numpy.set_printoptions(threshold='nan')
。这样后续的打印ndarray
就不会省略中间数据。
3. ndarray 算术运算和比较运算
ndarray
的算术运算、比较操作都是元素级的操作并且产生一个 ndarray
对象作为结果。 ndarray
的算术运算符 +, -, *, /, //, %, divmod(), ** or pow(), <<, >>, &, ^, |, ~
以及比较运算符 ==, <, >, <=, >=, !=
等价于相应的 numpy
中的 universal function
。
注意:
- 如果两个
ndarray
的元素类型不相同,则四则运算结果的类型由精度最高的那个ndarray
决定。 ndarray
支持原地算术操作,如+=
、*=
等,他会原地修改已存在的数组而不是创建一个新的数组。ndarry
的矩阵*
运算执行的是元素级相乘,而不是数学上的矩阵乘法。如果你想执行矩阵乘法, 可以使用numpy.dot(array1,array2)
实现两个ndarray
的矩阵乘法。你也可以通过array1.dot(array2)
实现同样的效果
4. 归一化操作
ndarray
支持若干归一化方法:
ndarray.sum()
:累加ndarray
所有元素的,并返回最终的和ndarray.min()
:返回所有元素的最小值ndarray.max()
:返回所有元素的最大值ndarray.cumsum()
:返回所有元素的累加和,返回累加和序列
对于这些方法你如果想在指定 axis
上操作,则可以提供 axis
关键字参数,其参数值从(0 到 ndim
)。默认情况下 axis=None
,表示将 ndarray
看作是一个一维的 ndarray
来操作。
5. 通用函数
numpy
提供常见的数学函数如 sin
、 cos
、 exp
等,这些函数作用于 ndarray
的每一个元素,因此称为通用函数( ufunc
)。所有的函数参考 https://docs.scipy.org/doc/numpy/reference/routines.html。
6. 索引、切片、迭代
- 一维数组可以被索引、切片、迭代,就像 Python 列表一样操作
- 多维数组可以每个轴一个索引。这些索引由一个逗号分割的元组给出。
- 当提供少于轴数的索引时,缺失的索引被认为是整个切片(必须提供前面的索引,可以缺失末尾的索引),如二维数组的
a[1]
- 如果想让缺失索引发生在前面,必须用
...
表示缺失索引。如二维数组的a[...,1]
;而a[1,...]
等价于a[1]
- 你也可以显式的用
:
指定整个切片
- 当提供少于轴数的索引时,缺失的索引被认为是整个切片(必须提供前面的索引,可以缺失末尾的索引),如二维数组的
- 多维数组的迭代仅仅只是迭代第一个轴。如果想迭代多维数组的每一个元素,可以用
ndarray.flat
属性,它是一个迭代器对象,迭代结果为ndarray
的所有元素
7. ndarray 的变形
ndarray
的形状由 ndarray.shape
属性给出,它是一个元组,指出每个轴上的元素个数。你可以通过以下函数改变一个 ndarray
的形状:
numpy.ravel(a,order='C')
:将a
展平,返回一个连续的一维ndarray
。a
是一个array-like
对象,它的读取顺序为order
(默认为 C 风格表示行优先读取)。- 如果
a
为ndarray
,则可以用ndarray.ravel(...)
方法,它等价于本函数
- 如果
numpy.resize(a,new_shape)
:返回一个新ndarray
,它是a
满足new_shape
的部分。其中a
为一个array-like
对象,而new_shape
为新数组的形状。如果new_shape
大于a
的形状,则新ndarray
复制a
来填充新的部分。所谓的复制就是:首先展开,然后循环复制,然后变形
numpy.reshape(a,newshape,order='C')
:返回a
的形状改变后的新ndarray
。a
为一个array-like
对象。newshape
必须与旧形状兼容(满足元素数量前后相同)。a
的读取顺序为order
(默认为 C 风格表示行优先读取)。- 如果
a
为ndarray
,则可以用ndarray.reshape(..)
方法,它等价于本函数
如果想改变
a
的形状,则直接修改a.shape
属性即可- 如果
8. ndarray 的拼接
有几种办法将 ndarray
拼接起来:
numpy.hstack(seq)
:水平拼接(即其他维度不变,维度 1 拼接),返回新创建的拼接后的ndarray
。seq
是一个序列,每个元素为一个array-like
对象或者ndarray
,且要求每个元素满足形状条件:除了维度 1 长度,其他维度长度必须相同。numpy.vstack(seq)
:垂直拼接(即其他维度不变,维度 0 拼接),返回新创建的拼接后的ndarray
。seq
是一个序列,每个元素为一个array-like
对象或者ndarray
,且要求每个元素满足形状条件:除了维度 0 长度,其他维度长度必须相同。numpy.column_stack(seq)
:将一维数组按列拼接成二维数组,返回新创建的拼接后的ndarray
。seq
是一个序列,每个元素为一个array-like
对象或者ndarray
,且要求是一维的。拼接规则为:第一维长度为原数组长度,第二维长度为 2,结果数组第二维每个元素为原来的数组序列中各取一个值的组成的数组。numpy.concatenate((a1, a2, ...), axis=0)
:将一系列数组按照指定轴线拼接,返回新创建的拼接后的ndarray
。a1、a2、....
都是array_like
对象,且要求每个元素满足形状条件:除了维度axis
长度,其他维度长度必须相同。axis
为拼接轴,默认为 0(以哪个轴为拼接轴,就变化该轴的长度)numpy.c_[a1,a2,...]
:沿着第二个轴拼接
9. ndarray 的拆分
有几种办法将 ndarray
拆分:
numpy.hsplit(array, indices_or_sections)
:将array
按照水平拆分(沿着 1 轴),返回一个ndarray
的列表。array
为一个ndarray
对象。numpy.vsplit(array, indices_or_sections)
:将array
按照垂直拆分(沿着 0 轴),返回一个ndarray
的列表。array
为一个ndarray
对象。indices_or_sections
:numpy.array_split(array, indices_or_sections,axis=0)
:将array
按照指定轴线axis
拆分,返回一个ndarray
的列表。array
为一个ndarray
对象。indices_or_sections
:
其共同的参数 indices_or_sections
:为一个整数标量或者一个一维数组。
- 如果是个整数
N
,则表示array
沿着均匀拆分轴拆成N
份。如果不能均匀拆分,则抛出异常 - 如果是个一维数组,则指示了拆分点。如
indices_or_sections
为[2,3]
,则表示拆分段为[0:2]
、[2:3]
、[3:]
。如果该一维数组中拆分点超过了轴线长度,则返回空的数组
10. ndarray 的拷贝和视图
当处理 ndarray
时,它的基础数据有时被拷贝,但有时并不被拷贝。有三种情况。
a. 完全不拷贝
简单的赋值操作并不拷贝 ndarray
的数据,这种情况下是新的变量引用 ndarray
对象(类似于列表的简单赋值)
b. 视图和浅拷贝
不同的 ndarray
可能共享相同的基础数据。 ndarray.view()
方法创建一个新的 ndarray
但是与旧 ndarray
共享相同的数据(即新 ndarray
并不拥有数据)。
- 对于视图,
ndarray.base
返回的是视图的底层ndarray
。而非视图ndarray.base
返回None
ndarray.flags.owndata
返回ndarray
是否拥有基础数据
对于 ndarray
的分片操作,它返回的是一个 ndarray
的视图。对 ndarray
的索引返回的不是视图,而是含有基础数据。
c. 深拷贝
ndarray.copy()
操作会返回一个完全的拷贝,不仅拷贝 ndarray
也拷贝基础数据。
11. 广播法则
当通用函数处理多个不同形状的 ndarray
时,需要使用广播法则来处理。使用广播法则的前提条件:两个 ndarray
的对应维度的长度,要么相等;如果不等则必须有一个长度为 1。不满足条件则不能使用广播法则。广播法则的条款是:
- 如果所有的输入数组维度不是完全相同,则某种规则将会被重复地添加数据到维度较小的
ndarray
的数组上直到所有的ndarray
拥有一样的维度。 - 添加规则:确定
ndarray
的维度为长度为 1 的轴的方向扩张,且扩张时填充的数据都相同,就是该轴的原始数据(因为该维度长度为 1)
12. 索引技巧
除了利用 Python 中的索引和分片规则之外, ndarray
还支持整数数组索引以及布尔数组索引。
a. 整数数组索引
索引数组每个整数是对 ndarray
的索引下标。其结果是一个 ndarray
的视图,外层维度由索引数组的维度,内层维度由 ndarray
的维度决定。
- 当被索引的
ndarray
是一个多维数组时,对它的索引是第 0 维的索引 - 当索引数组是一个多维数组时,每一维的索引数组必须有相同的形状
- 这里你可以将索引数组放入序列中,如
a[[index1,index2]]
,它等价于a[index1,index2]
。注意这里的
index1、index2
均为索引数组。如果都是整数则a[[inti,intj]]
(返回ndarray
) 不等于a[inti,intj]
(返回标量)。
- 这里你可以将索引数组放入序列中,如
- 你可以使用数组索引作为目标来赋值。
- 假设左侧被赋值的维度为 m1×n1,则右侧赋值数据的维度可以为:m1×n1、m1×1、1×n1、1*1(标量)。 如果不满足则抛出异常。
- 左侧的索引包含重复时,赋值被多次完成。保留最后的值。(要小心 Python 的+=结构)
b. 通过布尔数组索引
通过布尔数组索引能够显式的选择数组中我们想要和不想要的元素。
- 最简单的方式就是使用和原数组一样形状的布尔数组
常用于一次性修改原数组的不规则位置处的值
- 我们也可以采取类似整数切片的方式,对于原数组的每一个维度我们给以一维的布尔数组来选择我们需要的切片
要求一维布尔数组的长度与你要切片的轴的长度一致
11. ix_()
ix_()
函数能够排列组一组向量中的值,从而获取所有排列组合的结果。它接受 N
个一维数组,返回一个 N
元素的元组,其中元组的第 k
个元素都是一个这样的 N
维数组 ndarray
:该 ndarray
第 k
维长度等于参数列表第 k
个参数向量长度,第 k
维的值就是参数列表第 k
个参数向量的值,除了第 k
维之外所有其他维度的长度为 1。
它的作用就是重排每一个向量,使得重排后每一个数组变成
N
维,然后这些数组依次占领第 0 维,第 1 维....第N-1
维,从而使得广播法则能够起作用。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论