继续来学习numpy:
一、索引和切片
前面学了用numpy来创建各种各样的数组,这些数组都是ndarray
对象,都支持索引和切片操作。ndarray
对象的索引与python中的list
基本一致:
>>> import numpy as np
>>> a=np.arange(1,6,1)
>>> a
array([1, 2, 3, 4, 5])
>>> a[0]#也是从0开始索引
1
>>> a[4]
5
#再看二维数组索引
>>> aa=np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> aa
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
>>> aa[0,0]
1
>>> aa[2,2]
9
更高维度数组元素的索引和上述方式大同小异,再来看切片,先用和列表一样的方法来试试:
>>> b=np.arange(0,10,1)
>>> b
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> b[4:]
array([4, 5, 6, 7, 8, 9])
>>> b[0:4]
array([0, 1, 2, 3])
>>> b[5:-1]
array([5, 6, 7, 8])
>>> b[0:5:2]
array([0, 2, 4])
可以发现,这种方法是完全可行的,还可以利用python内置函数slice
进行切片:
>>> b[slice(1,8,2)]#取出b中从索引1开始到索引8的元素,间隔为2
array([1, 3, 5, 7])
看完了一维数组,再来看看二维数组元素的切片,二维数组里边我们经常有取一整列或者一整行的需求,可以使用...
和:
来进行切片,具体操作如下:
>>> bb=np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> bb
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
>>> bb[...,0]#取数组bb里第一列元素
array([1, 4, 7])
>>> bb[:,0]#跟bb[...,0]作用相同
array([1, 4, 7])
>>> bb[1,...]#取数组bb里第一行元素
array([4, 5, 6])
>>> bb[1,:]#跟bb[1,...]作用相同
array([4, 5, 6])
#还可以取几列或者几行元素
>>> bb[:,0:2]#取第0列和第1列全部元素
array([[1, 2],
[4, 5],
[7, 8]])
>>> bb[0:2,:]#取第0行和第1行的全部元素
array([[1, 2, 3],
[4, 5, 6]])
>>> bb[0:2,1:3]#取第0行和第1行上第1列和第2列的元素
array([[2, 3],
[5, 6]])
>>> bb[:]#取全部元素
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
二、数组变形
numpy里面的数组,还可以进行变形操作,主要有以下几种操作:
1.改变数组形状
在numpy中,封装了reshape函数来对数组进行变形操作,它一共接收三个参数:numpy.reshape(arr, newshape, order='C')
,各个参数的描述如下:
参数 | 描述 |
---|---|
arr | 需要修改形状的数组 |
reshape | 修改后数组的形状,传入的应该是整数或者整数数组,而且总的元素数量应该与arr一致 |
order | ‘C’ – 按行,’F’ – 按列,’A’ – 原顺序,’k’ – 元素在内存中的出现顺序 |
来看一下例子:
>>> a1=np.arange(1,10,1)
>>> a1
array([1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a2=np.reshape(a1,[3,3])
>>> a2
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
>>> a3=np.reshape(a1,[3,3],order='F')
>>> a3
array([[1, 4, 7],
[2, 5, 8],
[3, 6, 9]])
>>> a4=np.reshape(a1,[3,3],order='A')
>>> a4
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
也可以使用a1.reshape()来进行数组变形,跟上面的效果一样
>>> a6=a1.reshape([3,3])
>>> a6
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
2.转置
矩阵转置有两种方法:
transpose函数
ndarray.T
二者基本上等价,来看个例子:>>> b1=np.arange(1,9,1).reshape([2,4]) >>> b1 array([[1, 2, 3, 4], [5, 6, 7, 8]]) >>> b2=np.transpose(b1) >>> b2 array([[1, 5], [2, 6], [3, 7], [4, 8]]) >>> b3=b1.T >>> b3 array([[1, 5], [2, 6], [3, 7], [4, 8]])
3.广播
我们知道,矩阵运算通常对矩阵的维度有要求,所以numpy里边用广播机制来使矩阵满足维度要求。当运算中的 2 个数组的形状不同时,numpy 将自动触发广播机制。如:
>>> import numpy as np
>>> a=np.array([[0,0,0],[1,1,1],[2,2,2],[3,3,3]])
>>> a
array([[0, 0, 0],
[1, 1, 1],
[2, 2, 2],
[3, 3, 3]])
>>> b=np.array([1,2,3])
>>> a+b
array([[1, 2, 3],
[2, 3, 4],
[3, 4, 5],
[4, 5, 6]]
广播机制内容较多,这里只简单介绍,详细学习可参考这篇博客
三、通用函数
通用函数,也可以称为ufunc,是一种在ndarray数据中进行逐元素操作的函数。某些简单函数接受一个或多个标量数值,并产生一个或多个标量数值,而通用函数就是对这些简单函数的向量化封装
3.1一元通用函数
有很多ufunc是简单的逐元素转换,比如sqrt
或者exp
函数:
>>> arr=np.arange(10)
>>> arr
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.sqrt(arr)
array([0. , 1. , 1.41421356, 1.73205081, 2. ,
2.23606798, 2.44948974, 2.64575131, 2.82842712, 3. ])
>>> np.exp(arr)
array([1.00000000e+00, 2.71828183e+00, 7.38905610e+00, 2.00855369e+01,
5.45981500e+01, 1.48413159e+02, 4.03428793e+02, 1.09663316e+03,
2.98095799e+03, 8.10308393e+03])
这类函数我们把它称为一元通用函数,在这里列举一些常见的一元通用函数:
函数名 | 描述 |
---|---|
abs、fabs | 逐元素的计算整数、浮点数或者复数的绝对值 |
sqrt | 计算每个元素的平方根(与$arr^{0.5}$等价) |
square | 计算每个元素的平方(与$arr^2$等价) |
exp | 计算每个元素的以自然底数为底的指数值$e^2$ |
log、log10、log2、log1p | 分别对应:自然对数(e为底)、对数10为底、对数2为底、$log(1+x)$ |
sign | 计算每个元素的符号值:1(表示正数)、0表示数字0、-1表示复数 |
ceil | 计算每个元素的向上取整(大于等于给定数字的最小整数) |
floor | 计算每个元素的向下取整(小于等于给定数字的最大整数) |
rint | 将每个元素保留整数位,并保持dtype |
modf | 将每个元素的整数位和小数位分开,并按数组形式返回 |
isnan | 判断各个元素是不是NAN(不是一个数值)并返回布尔值数组 |
isfinite、isinf | 判断数组中各元素是否有限、是否无限,并返回布尔值数组 |
cos、cosh、sin、sinh、tan、tanh | 常规的双曲三角函数 |
arccos、arccosh、arcsin、arcsinh、arctan、arctanh | 反三角函数 |
logical_not | 对数组的元素按位取反(与-arr等价) |
3.2二元通用函数
还有一些通用函数,比如add或者maximum则会接收两个数组并返回一个数组作为结果,因此成为二元通用函数,在这列举一些:
函数名 | 描述 |
---|---|
add | 将数组的对应元素相加 |
subtract | 在第二个数组中,将第一个数组中包含的元素去除 |
multiply | 将数组的对应元素相乘 |
devide、floor_devide | 除或整除(放弃余数) |
power | 将第二个数组的元素作为第一个数组对应元素的幂次方 |
maximum、fmax | 逐个元素计算最大值,fmax会忽略NaN |
minimum、fmin | 逐个元素计算最小值,fmin会忽略NaN |
mod | 按元素的求模计算(即求除法的余数) |
copysign | 将第一个数组的符号值改为第二个数组的符号值 |
greater、greater_equal、less、less_equal、equal、not_equal | 进行逐个元素的比较,返回布尔值数组(分别与数学操作符>,>=,<,<=,==,!= 对应效果一致) |
logical_and、logical_or、logical_xor | 进行逐个元素的逻辑操作,与逻辑操作`&, |