3.1.6 其他常用操作
除上述常用操作外,还有一些其他操作,这里简单列举几种。
1.数组排序
尽管Python中内置了sort和sorted函数对列表进行排序,但NumPy的np.sort函数实际上效率更高。默认情况下,np.sort的排序算法是快速排序,其算法复杂度为NlogN,另外,也可以选择归并排序和堆排序。对于大多数应用场景,默认的快速排序已经足够高效了。如果想在不修改原始输入数组的基础上返回一个排好序的数组,可以使用np.sort函数。
In [127]: array1 = np.random.randn(8) In [128]: array1 Out[128]: array([ 2.32922766e-03, -4.65499947e-01, -1.05467673e+00, -4.87072122e-01, 1.13967269e+00, -2.67169310e+00, -1.17234641e+00, -1.21430879e-01]) In [129]: np.sort(array1) Out[129]: array([-2.67169310e+00, -1.17234641e+00, -1.05467673e+00, -4.87072122e-01, -4.65499947e-01, -1.21430879e-01, 2.32922766e-03, 1.13967269e+00])
可以看到,如果不指定,np.sort函数默认是按升序排列的。另外,还可以通过设置axis参数对多维数组的行或列进行排序。参数axis=0、axis=1分别表示按行、按列进行排序。
In [130]: array2 = np.random.randint(0,10,size=(3,3)) In [131]: array2 Out[131]: array([[7, 9, 3], [0, 7, 6], [5, 0, 4]]) In [132]: np.sort(array2,axis=0) Out[132]: array([[0, 0, 3], [5, 7, 4], [7, 9, 6]]) In [133]: np.sort(array2,axis=1) Out[133]: array([[3, 7, 9], [0, 6, 7], [0, 4, 5]])
2.数组统计
前面介绍了部分常用的数组函数,其实数组中的数学统计方法在实际应用中也经常用到,它们表示对整个数组或某个轴进行数据统计计算,如表3-2所示。
表3-2 常用的数组函数
与排序类似,mean和sum这些函数同样可以接收一个axis参数,用于对某个轴进行统计,若不加以指明,则默认对整个数组进行统计。
In [134]: array3 = np.array([[1,2,3],[4,5,6],[7,8,9]]) In [135]: array3 Out[135]: array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) In [136]: array3.sum() Out[136]: 45 In [137]: array3.sum(axis=0) Out[137]: array([12, 15, 18]) In [138]: array3.mean() Out[138]: 5.0 In [139]: array3.mean(axis=1) Out[139]: array([2., 5., 8.]) In [140]: array3.min() Out[140]: 1 In [141]: array3.max() Out[141]: 9
3.线性代数运算
NumPy中支持线性代数运算功能,可以轻松实现对数组或者矩阵的快速运算。dot函数就是常用于求数组或者矩阵乘法的典型函数,另外NumPy.linalg中也有一组标准的矩阵分解、矩阵求逆以及求行列式等函数。
In [142]: a = np.array([[1.5,2.5,3.5],[4.5,5.5,6.6]]) In [143]: b = np.array([[4.0,6.8],[-2.3,9.6],[5.2,6.1]]) In [144]: a.dot(b) Out[144]: array([[ 18.45, 55.55], [ 39.67, 123.66]])
这里的dot函数表示矩阵乘法,与前面介绍的矩阵相乘规则相同,即A*B,但与矩阵点乘(multiply)不同,需要注意区分。
通过inv函数求矩阵(方阵)的逆:
In [146]: from NumPy.linalg import inv In [147]: X = np.matrix(np.random.rand(3,3)) In [148]: X Out[148]: matrix([[0.24433453, 0.92087325, 0.7367185 ], [0.14273623, 0.29192359, 0.75203012], [0.77675993, 0.53315501, 0.51086317]]) In [149]: inv(X) Out[149]: matrix([[-0.84428363, -0.26036073, 1.60081706], [ 1.71403818, -1.50014299, -0.26349705], [-0.50511052, 1.96147735, -0.20155255]])
还有另外一种快速求矩阵的逆的方法,即通过.I实现。
In [150]: X.I Out[150]: matrix([[-0.84428363, -0.26036073, 1.60081706], [ 1.71403818, -1.50014299, -0.26349705], [-0.50511052, 1.96147735, -0.20155255]])
需要注意的是,只有在矩阵为方阵(行数和列数相等)的情况下,才可以求矩阵的逆。
4.随机数生成
NumPy.random模块对Python内置的random进行了补充,增加了一些用于快速生成多种概率分布的随机数的函数。例如,我们可以通过normal来得到一个服从标准正态分布的样本数组:
In [151]: samples = np.random.normal(size=(3,3)) In [152]: samples Out[152]: array([[ 0.42745142, 1.07576515, 0.77186596], [ 0.76190693, 0.31185696, -0.72752961], [ 0.06208286, -0.65498485, -0.15007811]])
可以通过rand生成服从均匀分布的样本数组:
In [153]: samples1 = np.random.rand(4,4) In [154]: samples1 Out[154]: array([[0.21082897, 0.0266671, 0.23973794, 0.5355538 ], [0.7134466, 0.3593146, 0.97527854, 0.14084089], [0.3238133, 0.87598642, 0.14541845, 0.62839632], [0.21154816, 0.30865245, 0.33729369, 0.54159844]])
我们还可以通过randint得到从给定的上下限范围内随机选取整数的样本数组等。
In [155]: samples3 = np.random.randint(0,10,size=(4,6)) In [156]: samples3 Out[156]: array([[9, 5, 0, 5, 4, 8], [9, 0, 4, 3, 1, 8], [4, 3, 0, 1, 3, 1], [5, 2, 9, 5, 0, 8]])