zoukankan      html  css  js  c++  java
  • Python数据分析工具库-Numpy 数组支持库(二)

    1 shape变化及转置

    >>> a = np.floor(10*np.random.random((3,4)))
    >>> a
    array([[ 2.,  8.,  0.,  6.],
           [ 4.,  5.,  1.,  1.],
           [ 8.,  9.,  3.,  6.]])
    >>> a.shape
    (3, 4)
    >>> a.ravel()  # 转化为一维数组
    array([ 2.,  8.,  0.,  6.,  4.,  5.,  1.,  1.,  8.,  9.,  3.,  6.])
    >>> a.reshape(6,2)  # 将数组a转化为指定shape的数组
    array([[ 2.,  8.],
           [ 0.,  6.],
           [ 4.,  5.],
           [ 1.,  1.],
           [ 8.,  9.],
           [ 3.,  6.]])
    >>> a.T  # 数组的转置
    array([[ 2.,  4.,  8.],
           [ 8.,  5.,  9.],
           [ 0.,  1.,  3.],
           [ 6.,  1.,  6.]])
    >>> a.T.shape
    (4, 3)
    >>> a.shape
    (3, 4)

    注意对数组进行reshape操作不会改变原有数组a,但resize会在原有数组a上进行改变:

    >>> a.resize((2,6))
    >>> a
    array([[ 2.,  8.,  0.,  6.,  4.,  5.],
           [ 1.,  1.,  8.,  9.,  3.,  6.]])

    当reshape方法中有参数为-1,则表示numpy会自己计算-1位置的维数,这在很多深度学习模型中可以见到。

    >>> a.reshape(3,-1)
    array([[ 2.,  8.,  0.,  6.],
           [ 4.,  5.,  1.,  1.],
           [ 8.,  9.,  3.,  6.]])

    2 数组的合并与拆分

    concatenate连接

    >>> x = numpy.array([[1, 2, 3], [4, 5, 6]])
    >>> y = numpy.array([[7, 8, 9], [10, 11, 12]])
    >>> numpy.concatenate([x, y], axis = 0)  # 竖直组合 
    [[ 1  2  3][ 4  5  6][ 7  8  9][10 11 12]]
    >>> numpy.concatenate([x, y], axis = 1)  # 水平组合
     [[ 1  2  3  7  8  9][ 4  5  6 10 11 12]]

    横向合并,沿第一个轴进行堆叠,比如:vstackrow_stack

    >>> a = np.floor(10*np.random.random((2,2)))
    >>> a
    array([[ 8.,  8.],
           [ 0.,  0.]])
    >>> b = np.floor(10*np.random.random((2,2)))
    >>> b
    array([[ 1.,  8.],
           [ 0.,  4.]])
    >>> np.vstack((a,b))
    array([[ 8.,  8.],
           [ 0.,  0.],
           [ 1.,  8.],
           [ 0.,  4.]])

    纵向合并,沿着第二个轴进行堆叠,比如hstackcolumn_stack,两者不一样,column_stack在对一维数组进行堆叠时会先将一维数组转化为二维数组,最终返回二维数组。

    >>> np.hstack((a,b)) #使用hstack对二维数组进行纵向合并
    array([[ 8.,  8.,  1.,  8.],
           [ 0.,  0.,  0.,  4.]])
    >>> np.column_stack((a,b)) #使用column_stack对二维数组进行纵向合并
    array([[ 8.,  8.,  1.,  8.],
           [ 0.,  0.,  0.,  4.]])
    >>> a = np.array([4.,2.])
    >>> b = np.array([3.,8.])
    >>> np.column_stack((a,b)) #使用column_stack对一维数组进行纵向合并,返回二维数组
    array([[ 4., 3.],
           [ 2., 8.]])
    >>> np.hstack((a,b))  #使用hstack对一维数组进行纵向合并,返回一维数组
    array([ 4., 2., 3., 8.])

    array_split ,numpy.array_split(ary, indices_or_sections, axis=0),沿着第一个轴从左至右的顺序切分:

    >>> x = np.arange(8.0)
    >>> np.array_split(x, 3)
        [array([ 0.,  1.,  2.]), array([ 3.,  4.,  5.]), array([ 6.,  7.])]
    >>> x = np.arange(7.0)
    >>> np.array_split(x, 3)
        [array([ 0.,  1.,  2.]), array([ 3.,  4.]), array([ 5.,  6.])]

    vsplit,沿着第一个轴切分,相当于split方法中参数axis=0

    >>> x = np.arange(16.0).reshape(4, 4)
    >>> x
    array([[  0.,   1.,   2.,   3.],
           [  4.,   5.,   6.,   7.],
           [  8.,   9.,  10.,  11.],
           [ 12.,  13.,  14.,  15.]])
    >>> np.vsplit(x, 2)
    [array([[ 0.,  1.,  2.,  3.],
           [ 4.,  5.,  6.,  7.]]),
     array([[  8.,   9.,  10.,  11.],
           [ 12.,  13.,  14.,  15.]])]

    hsplit,沿着第二个轴切分,相当于split方法中参数axis=1

    >>> x = np.arange(16.0).reshape(4, 4)
    >>> x
    array([[  0.,   1.,   2.,   3.],
           [  4.,   5.,   6.,   7.],
           [  8.,   9.,  10.,  11.],
           [ 12.,  13.,  14.,  15.]])
    >>> np.hsplit(x, 2)
    [array([[  0.,   1.],
           [  4.,   5.],
           [  8.,   9.],
           [ 12.,  13.]]),
     array([[  2.,   3.],
           [  6.,   7.],
           [ 10.,  11.],
           [ 14.,  15.]])]

    3 数组的复制

    完全不复制(No Copy at All)

    >>> a = np.arange(12)
    >>> b = a            # no new object is created
    >>> b is a           # a and b are two names for the same ndarray object
    True
    >>> b.shape = 3,4    # changes the shape of a
    >>> a.shape
    (3, 4)

    这种方式的“复制”其实没有实际复制,只是将变量b在内存的索引指向了变量a所在的内存,这样变量a和变量b均指向同一块内存,这时候改变了b就相当于改变了a

    浅复制

    使用view方法来创建一个新的数组对象,并把将被复制的数组a的视图(view)复制到新的数组对象c中,这时的c数据完全来自于a,和 a 保持完全一致,换句话说,c的数据完全由a保管,他们两个的数据变化是一致的:

    >>> c = a.view()
    >>> c is a
    False
    >>> c.base is a       # c只是a的视图
    True
    >>> c.flags.owndata
    False
    >>> c.shape = 2,6   # a的shape不会变化
    >>> a.shape
    (3, 4)
    >>> c[0,4] = 1234   # a的值会相应的变化
    >>> a
    array([[   0,    1,    2,    3],
           [1234,    5,    6,    7],
           [   8,    9,   10,   11]])

    切片也是一种浅复制:

    >>> s = a[ : , 1:3]     # 将a的第2列与第三列浅复制给s
    >>> s[:] = 10           # 将s的所有元素重新赋值为10,也会改变a相应位置的值
    >>> a
    array([[   0,   10,   10,    3],
           [1234,   10,   10,    7],
           [   8,   10,   10,   11]])

    深复制

    使用copy方法,不仅将被复制数组的索引复制到新的数组中,也将被复制数组的元素复制到新的数组中。

    >>> d = a.copy()      # 创建一个新的数组
    >>> d is a
    False
    >>> d.base is a     
    False
    >>> d[0,0] = 9999
    >>> a
    array([[   0,   10,   10,    3],
           [1234,   10,   10,    7],
           [   8,   10,   10,   11]])

    4 Fancy indexing与布尔索引

    Fancy indexing是指传递索引数组以便一次得到多个数组元素。使用Fancy indexing时返回数组的shape是索引数组的shape而不是被索引的原数组的shape

    一维数组的Fancy indexing

    >>> a = np.arange(12)**2     
    >>> i = np.array( [ 1,1,3,8,5 ] )    # 索引数组
    >>> a[i]                                      
    array([ 1,  1,  9, 64, 25])
    >>> j = np.array( [ [ 3, 4], [ 9, 7 ] ] )   
    >>> a[j]                       
    array([[ 9, 16],
           [81, 49]])

    多维数组的Fancy indexing

    >>> a = np.arange(12).reshape(3,4)
    >>> a
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> i = np.array( [ [0,1],      # 横向索引
    ...                 [1,2] ] )
    >>> j = np.array( [ [2,1],      # 纵向索引 
    ...                 [3,3] ] )
    >>>
    >>> a[i,j]                
    array([[ 2,  5],
           [ 7, 11]])
    >>> a[i,2]
    array([[ 2,  6],
           [ 6, 10]])
    >>>
    >>> a[:,j]             
    array([[[ 2,  1],
            [ 3,  3]],
           [[ 6,  5],
            [ 7,  7]],
           [[10,  9],
            [11, 11]]])

    如果索引数组包含多个相同的索引,那么最后的索引会覆盖前面的索引。

    >>> a = np.arange(5)
    >>> a[[0,0,2]]=[1,2,3]
    >>> a
    array([2, 1, 3, 3, 4])

    但对于类似“+=”累加的操作却不会叠加两次:

    >>> a = np.arange(5)
    >>> a[[0,0,2]]+=1
    >>> a
    array([1, 1, 3, 3, 4])

    布尔索引

    索引数组元素为布尔类型的值:

    >>> a = np.arange(12).reshape(3,4)
    >>> b = a > 4
    >>> b                        
    array([[False, False, False, False],
           [False,  True,  True,  True],
           [ True,  True,  True,  True]])
    >>> a[b]                   
    array([ 5,  6,  7,  8,  9, 10, 11])
    >>> a[b] = 0                
    >>> a
    array([[0, 1, 2, 3],
           [4, 0, 0, 0],
           [0, 0, 0, 0]])

    索引数组有多个

    >>> a = np.arange(12).reshape(3,4)
    >>> b1 = np.array([False,True,True])             
    >>> b2 = np.array([True,False,True,False])      
    
    >>> a[b1,:]                                  
    array([[ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    
    >>> a[b1]                                    
    array([[ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    
    >>> a[:,b2]                                
    array([[ 0,  2],
           [ 4,  6],
           [ 8, 10]])

    5 Numpy的线性代数(Linear Algebra)

    包含求逆、奇异值分解、生成对角矩阵、解线性方程组Ax=b、计算特征值与特征向量等

    >>> import numpy as np
    >>> a = np.array([[1.0, 2.0], [3.0, 4.0]])
    >>> print(a)
    [[ 1.  2.]
     [ 3.  4.]]
    
    >>> a.transpose() # 转置
    array([[ 1.,  3.],
           [ 2.,  4.]])
    
    >>> np.linalg.inv(a) # 求逆
    array([[-2. ,  1. ],
           [ 1.5, -0.5]])
    
    >>> u = np.eye(2) # 生成对角矩阵
    >>> u
    array([[ 1.,  0.],
           [ 0.,  1.]])
    >>> j = np.array([[0.0, -1.0], [1.0, 0.0]])
    
    >>> np.dot (j, j) # 矩阵乘
    array([[-1.,  0.],
           [ 0., -1.]])
    
    >>> np.trace(u)  # 求对角线元素和
    2.0
    
    >>> y = np.array([[5.], [7.]])
    >>> np.linalg.solve(a, y) # 解线性方程组Ax=b
    array([[-3.],
           [ 4.]])
    
    >>> np.linalg.eig(j) #计算特征值与特征向量
    (array([ 0.+1.j,  0.-1.j]), array([[ 0.70710678+0.j        ,  0.70710678-0.j        ],
           [ 0.00000000-0.70710678j,  0.00000000+0.70710678j]]))

    参考文献 厦工叉车

    Numpy API文档:https://docs.scipy.org/doc/

  • 相关阅读:
    并发和并行的区别
    fiddler-打断点(bpu)
    fiddler操作
    fiddler手机抓包
    面试题1
    Linux查看日志常用命令
    HTMLTestRunner
    mysql数据库无法插入特殊字符报错
    mybatis解决属性名和数据库字段名不一致问题
    Vue路由的使用简单实例
  • 原文地址:https://www.cnblogs.com/xyou/p/9114870.html
Copyright © 2011-2022 走看看