前言
numpy提供了很多对数组进行逐元素运算的函数,可以大大提高运算效率。
PS: 这篇文章是我写的numpy知识总结的一部分,完整知识总结入口在这篇文章,在这篇文章里我搭建了numpy的基础知识框架,非常适合入门。
numpy数组之所以重要是因为它允许我们进行批量操作而无需任何for循环。这一特性通常称为向量化。
【例1】同尺寸数组之间的计算示例
In [315]: arr = np.array([[1,2,3],[4,5,6]],dtype = np.float64)
In [316]: arr
Out[316]:
array([[1., 2., 3.],
[4., 5., 6.]])
In [317]: arr*arr
Out[317]:
array([[ 1., 4., 9.],
[16., 25., 36.]])
In [318]: arr - arr
Out[318]:
array([[0., 0., 0.],
[0., 0., 0.]])
【例2】带标量的计算示例
In [320]: arr
Out[320]:
array([[1., 2., 3.],
[4., 5., 6.]])
In [321]: 1 / arr
Out[321]:
array([[1. , 0.5 , 0.33333333],
[0.25 , 0.2 , 0.16666667]])
In [322]: arr ** 0.5
Out[322]:
array([[1. , 1.41421356, 1.73205081],
[2. , 2.23606798, 2.44948974]])
【例3】同尺寸数组之间的比较示例
In [327]: arr
Out[327]:
array([[1., 2., 3.],
[4., 5., 6.]])
In [328]: arr2
Out[328]:
array([[ 0., 4., 1.],
[ 7., 2., 12.]])
In [329]: arr2 > arr
Out[329]:
array([[False, True, False],
[ True, False, True]])
通用函数的调用方式为:
np.ufunc(arr) //对数组arr执行ufunc
对于返回值的接收有两种方式:
方式一: arr1 = np.ufunc(arr) // arr1可以是一个未声明过的变量
方式二: np.ufunc(arr, arr2) //arr2必须是跟arr形状相同且声明过的数组
以上第一种方式是直接接收函数的返回值,对于接收返回值的变量没有什么要求;第二种方式则要求arr2必须是跟arr形状相同的数组,如果为了接收返回值用这种方式就显得很麻烦,所以第二种方式中的arr2通常就是arr,这一方式常用作对数组自身的操作。
【例】通用函数返回值接收示例
In [344]: arr
Out[344]: array([0.71755774, 0.97190265, 0.76586881, 0.95047457, 0.37077581])
#通过其他变量接收返回值
In [345]: arr1 = np.sqrt(arr)
In [346]: arr1
Out[346]: array([0.8470878 , 0.98585123, 0.87513931, 0.97492286, 0.60891363])
In [347]: arr
Out[347]: array([0.71755774, 0.97190265, 0.76586881, 0.95047457, 0.37077581])
#对arr自身进行操作
In [348]: np.sqrt(arr,arr)
Out[348]: array([0.8470878 , 0.98585123, 0.87513931, 0.97492286, 0.60891363])
In [349]: arr
Out[349]: array([0.8470878 , 0.98585123, 0.87513931, 0.97492286, 0.60891363])
函数名 | 描述 |
---|---|
abs、fabs | 逐元素地计算整数、浮点数或复数的绝对值 |
sqrt | 计算每个元素的平方根(与arr**0.5相等) |
aquare | 计算每个元素的平方(与arr ** 2相等) |
exp | 计算每个元素的自然指数值 e x e^x ex |
log、log10、log2、log1p | 分别对应:自然对数(e为底)、对数10为底、对数2为底、log(1+x) |
sign | 符号函数,计算每个元素的符号值:1(正数)、0(0)、-1(负数) |
ceil | 计算每个元素的最高整数值,上取整 |
floor | 计算每个元素的最小整数值,下取整 |
rint | 将元素保留到整数位,并保持dtype;采用四舍五入,大于1时,1.5~2,小于1时,0.5~0 |
modf | 分别将数组的小数部分和整数部分按数组形式返回,返回值是两个数组,第一个是小数部分组成的数组,第二个是整数组成的数组 |
isnan | 返回数组中的元素是否是一个NaN,形式为布尔值数组 |
isfinite、isinf | 分别返回数组中的元素是否有限(非inf、非NaN)、是否无限的,形式为布尔值数组 |
cos、cosh、sin、sinh、tan、tanh | 常规的双曲三角函数 |
arccos、arccosh、arcsin、arcsinh、arctan、arctanh | 反三角函数 |
logical_not | 对数组的元素按位取反(与~arr效果一致) |
【例】部分一元函数使用示例
In [361]: arr
Out[361]: array([0.4 , 0.5 , 0.51, 0.6 , 1.4 , 1.49, 1.5 , 1.6 ])
In [362]: arr = np.array([-1.5,-0.5,0.4, 0.5, 0.51, 0.6, 1.4,1.49, 1.5, 1.6])
In [363]: arr
Out[363]:
array([-1.5 , -0.5 , 0.4 , 0.5 , 0.51, 0.6 , 1.4 , 1.49, 1.5 ,
1.6 ])
In [364]: np.rint(arr)
Out[364]: array([-2., -0., 0., 0., 1., 1., 1., 1., 2., 2.])
In [365]: f,s = np.modf(arr)
In [366]: f
Out[366]:
array([-0.5 , -0.5 , 0.4 , 0.5 , 0.51, 0.6 , 0.4 , 0.49, 0.5 ,
0.6 ])
In [367]: s
Out[367]: array([-1., -0., 0., 0., 0., 0., 1., 1., 1., 1.])
函数名 | 描述 |
---|---|
add | 将数组的对应元素相加,与算数运算中的加法相同 |
subtract | 在第二个数组中,将第一个数组中包含的元素去除 |
multiply | 将数组的对应元素相乘 |
divide, floor_divide | 除或整除(放弃余数) |
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 | 逐个元素的逻辑操作(与逻辑操作符&、|、^效果一致) |
矩阵乘法、分解、行列式等方阵数学,是所有数组类库的重要组成部分。在numpy中,* 是逐元素相乘,矩阵乘法即点乘使用dot()函数,也可使用 @ 。在numpy中,矩阵的转置使用 .T。
x.dot(y) 等价于 dot(x,y) 等价于 x @ y
numpy将矩阵的其他操作都放在numpy.linalg包中,如矩阵分解、求逆、行列式分解等。
函数 | 描述 |
---|---|
diag | 将一个方阵的对角(或非对角)元素作为一维数组返回,或者将一维数组转换成一个方阵,并且在非对角线上有零点 |
dot | 矩阵点乘 |
trace | 计算对角元素和 |
det | 计算矩阵的行列式 |
eig | 计算方阵的特征值和特征向量 |
inv | 计算方阵的逆矩阵 |
pinv | 计算矩阵的Moore-Penrose伪逆 |
qr | 计算QR分解 |
svd | 计算奇异值分解(SVD) |
solve | 求解x的先行系统Ax=b,其中A是方阵 |
lstsq | 计算Ax=b的最小二乘解 |
【例1】数组的点乘与转置
In [392]: x
Out[392]:
array([[1., 2., 3.],
[4., 5., 6.]])
In [394]: y
Out[394]:
array([[ 6., 23.],
[-1., 7.],
[ 8., 9.]])
In [395]: x.T
Out[395]:
array([[1., 4.],
[2., 5.],
[3., 6.]])
In [396]: x.dot(y)
Out[396]:
array([[ 28., 64.],
[ 67., 181.]])
In [397]: np.dot(x,y)
Out[397]:
array([[ 28., 64.],
[ 67., 181.]])
In [398]: x @ y
Out[398]:
array([[ 28., 64.],
[ 67., 181.]])