Python广告数据挖掘与分析实战
上QQ阅读APP看书,第一时间看更新

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]])