zoukankan      html  css  js  c++  java
  • 一、Numpy库与多维数组

    # Author:Zhang Yuan
    import numpy as np
    '''重点摘录:
    轴的索引axis=i可以理解成是根据[]层数来判断的,0表示[],1表示[[]]...
    Numpy广播的规则可理解成:结构相同,点对点;结果不同,分别匹配。[]是最小单元,按最小单元匹配。
    Numpy中逻辑尽量用逻辑操作运算符&/|,少用关键字and/or
    Numpy的向量化操作比纯Python速度更快。
    ndarray的基本运算 + - * /  // 等... 会调用对应的通用函数,为数组中元素的运算。
    '''
    #NumPy 最重要的一个特点是其 N 维数组对象 ndarray。
    
    #ndarray对象的维度是通过多层[]来确定的。[...]表示一维数据,[[...]]表示二维数据,[[[...]]]表示三维数据...
    #轴的索引axis=i是根据[]层数来判断的,0表示[],1表示[[]]...
    
    # [,]中的逗号,表示当前所在维度层的数据划分。[1,2,3] 一维划分。[[1, 2], [3, 4]] 外部逗号为第一层维度(行)划分,内部逗号为第二层维度(列)的划分
    
    # int8, int16, int32, int64 四种数据类型可以使用字符串 'i1', 'i2','i4','i8' 代替
    
    #赋值系列---------------------------------------------------------------
    #原数据输入的方式形成数组:
    #原数据输入可以是各种类型。
    #"层次相同、数据个数相同"会默认转成多维数组,也就是严格符合多维数组格式的会自动转换.
    print(np.array([1,2,[3]]))  #[1 2 list([3])],只有一个二层次
    print(np.asarray([(1,),2,[3]]))  #[(1,) 2 list([3])],只有一个一层次
    print(np.array([(1,),(2,),[3,]]))  #[[1],[2],[3]],都是二层次,转换
    print(np.asarray([(1,),(2,),(3,)]))  #[[1],[2],[3]],都是二层次,转换
    print(np.array([(1,2),(3,)]))  #[(1, 2) (3,)],都二层,但大小不同
    print(np.asarray([(1,2),(3,4)]))  #[[1, 2],[3, 4]],都二层且大小相同,转换
    
    #创建的方式形成数组:
    #以shape维度描述来创建。
    print(np.zeros((3,2))) #empty(),ones()
    #以buffer来创建,用于实现动态数组。
    #buffer 是字符串的时候,Python3 默认 str 是 Unicode 类型,所以要转成 bytestring 在原 str 前加上 b。
    print(np.frombuffer(b'Hello World',dtype =  'S1'))
    print(np.frombuffer(np.array([1,2,3,4,5]),dtype=int))
    #以迭代对象来创建
    print(np.fromiter(range(5),dtype=int))
    #以数值范围来创建
    print(np.arange(10,20,2)) #[10  12  14  16  18]
    print(np.linspace(1,10,10)) #[ 1.  2.  3.  4.  5.  6.  7.  8.  9. 10.]
    print(np.logspace(1,2,num=2)) #[ 10. 100.]
    #--------------------------------------------------------------------------
    
    #访问系列------------------------------------------------------------------
    #切片还可以包括省略号 ...,来使选择元组的长度与数组的维度相同。如果在行位使用省略号,它将返回包含行中元素的 ndarray
    #多维数组的切片和索引[,]中第一层逗号表示维度划分,第一层逗号分割的左右部分一定是按照维度顺序.
    #多维数组若没有第一层逗号,会默认加上第一层逗号。但仅传入元组逗号省略。
    a = np.array([[1,2,3],[4,5,6],[7,8,9]])
    print(a[...,1:]) # [[2 3],[5 6],[8 9]],相当于a[:,1:].
    print(a[(1,2)])  # 6, 仅传入元组括号省略:a[1,2]=6.
    print(a[[1,2]])  # [[4 5 6],[7 8 9]], 默认加上第一层逗号,相当于a[[1,2],]
    print(a[[-1,-3]]) #[[7 8 9],[1 2 3]], 默认加上第一层逗号,相当于a[[-1,-3],]
    print(a[(1,2),]) # [[4 5 6],[7 8 9]],相当于a[(1,2),:],行1、2,列全部
    
    #多维多值索引一定要一一配对,且输出形式与输入的索引形式相同
    print(a[[0,1,2], [0,1,0]])  #[1 5 7],多值索引。一对一:0-0,1-1,2-0
    print(a[ [ [0,0],[2,2] ] , [ [0,2],[0,2] ] ]) #[[1 3], [7 9]]
    print(a[np.array([[1],[2]]),np.array([[0],[2]])]) #[[4], [9]]
    print(a[ [[1],[2]] , [[0],[2]] ]) #[[4], [9]]
    
    #多维多值索引各维度层次不同,会自动默认到最高层次.
    #各维度表示形式相同,点对点匹配,且大小必须相同。各维度表示形式不同,以不同的形式分别匹配。
    x=np.arange(12).reshape((3,4))
    '''x=array([[0, 1, 2,  3],
                [4, 5, 6,  7],
                [8, 9, 10, 11]])'''
    print(x[ [1,2,0] , [[[3,1,0]]] ]) #[[[7 9 0]]] 各维度表示形式相同,点对点匹配;层次不同,会自动默认到最高层次.
    x1=x[ [[1],[2],[0]] , [[3,1,0]] ] #[x]配 [a,b,c,d]表示:按a,b,c,d顺序索引第x行
    '''x1=array([[ 7,  5,  4],
                 [11,  9,  8],
                 [ 3,  1,  0]]) '''
    
    x2=x[ [[1,2,0]] , [[3],[1],[0]] ] #[a,b,c,d]配[x]表示:按a,b,c,d顺序索引第x列
    '''x2=array([[ 7, 11,  3],
                 [ 5,  9,  1],
                 [ 4,  8,  0]])'''
    #其中x1、x2互为转置矩阵
    
    #第一维行为变独立( array([[1],[3]]), array([[2, 5]]) )
    np.ix_([1,3],[2,5])
    print(x[np.ix_([1,2,0],[3,1,0])])
    '''[ [ 7  5  4]
         [11  9  8]
         [ 3  1  0] ]'''
    
    #以布尔数组np.array([True,False,...])形式可以过滤
    x= np.array([1,2,3,4,5,6])
    x[np.array([True,False,True,False,True,False])] #array([1, 3, 5])
    x[x > 2] #array([3, 4, 5, 6])
    a = np.array([np.nan,  1,2,np.nan,3,4,5])
    print(a[~np.isnan(a)]) #[1. 2. 3. 4. 5.],其中 ~ 取补运算符,按位取反.
    #----------------------------------------------------------------------
    
    #当运算中的 2 个数组的形状不同时,但要具备拉升可匹配性Broadcasting,numpy 会把数组自动拉升Broadcasting到相同,在进行元素运算
    
    #numpy中运算函数也会遵循匹配性Broadcasting原则。
    
    #对于一个多维数组a,如果a已经分配内存了,其转置a.T与a共享内存,且存储顺序也是一样的。
    # 如果希望a.T与a存储顺序不同,可以需要重新分配内存:a.T.copy()。
    # 或者控制遍历顺序:
    # for x in np.nditer(a, order='F'):Fortran order,即是列序优先;
    # for x in np.nditer(a.T, order='C'):C order,即是行序优先;
    
    #注意numpy中纬度是:011---轴0、1、2---轴Z、Y、X,新增的纬度放入轴索引0
    #一维数据:0轴-X轴;二维数据:0轴-Y轴-列数据、1轴-X轴-行数据;...
    
    # Numpy数组操作------------------------------------------------------
    # 修改数组形状:
    #     reshape    不改变数据的条件下修改形状
    #     flat    数组元素迭代器
    #     flatten    返回一份数组拷贝,对拷贝所做的修改不会影响原始数组
    #     ravel    返回展开数组
    # 翻转数组:
    #     transpose    对换数组的维度
    #     ndarray.T    和 self.transpose() 相同
    #     rollaxis    向后滚动指定的轴
    #     swapaxes    对换数组的两个轴
    # 修改数组维度:
    #     broadcast    产生模仿广播的对象
    #     broadcast_to    将数组广播到新形状
    #     expand_dims    扩展数组的形状
    #     squeeze    从数组的形状中删除一维条目
    # 连接数组
    #     concatenate    连接沿现有轴的数组序列
    #     stack    沿着新的轴加入一系列数组。
    #     hstack    水平堆叠序列中的数组(列方向)
    #     vstack    竖直堆叠序列中的数组(行方向)
    # 分割数组
    #     split    将一个数组分割为多个子数组
    #     hsplit    将一个数组水平分割为多个子数组(按列)
    #     vsplit    将一个数组垂直分割为多个子数组(按行)
    # 数组元素的添加与删除
    #     resize    返回指定形状的新数组
    #     append    将值添加到数组末尾
    #     insert    沿指定轴将值插入到指定下标之前
    #     delete    删掉某个轴的子数组,并返回删除后的新数组
    #     unique    查找数组内的唯一元素
    
    #使用细节:
    #flat数组元素迭代器
    a = np.arange(9).reshape(3,3)
    for row in a:print(row) #打印行
    for element in a.flat:print (element) #打印元素
    
    #可以先定义格式,再赋值
    c=np.empty((4,3))
    c.flat=[i for i in range(12)]
    
    #运算也遵循相同结构点对点,不同结构分配匹配原则
    x = np.array([[7], [8], [9]])
    x1= np.array([7, 8, 9])
    y = np.array([4, 5, 6])
    print(x+y)  #结果不同,分别运算。
    print(x1+y) #结构相同,一对一运算。
    print(x*y)  #结果不同,分别运算。
    print(x1*y) #结构相同,一对一运算。
    
    #numpy.swapaxes函数用于交换数组的两个轴
    #注意numpy中纬度是:011---轴0、1、2---轴Z、Y、X,新增的纬度放入轴索引0
    x=np.arange(8).reshape((2,2,2))
    print(x)
    print (np.swapaxes(x, 0, 2))
    
    #np.expand_dims()原理
    x=np.array([1,2,3,4])
    print(x)                        #[1 2 3 4]
    print(np.expand_dims(x,axis=0)) #[[1 2 3 4]] 相当于在第一层[]或第零层元素上加个[]
    print(np.expand_dims(x,axis=1)) #[[1],[2],[3],[4]] 相当于在第二层[]或第一层元素上加个[]
    y=np.array([[1,2],[3,4]])
    print(y)                        #[[1 2],[3 4]]
    print(np.expand_dims(y,axis=0)) #[[[1 2],[3 4]]] 相当于在第一层[]或第零层元素上加个[]
    print(np.expand_dims(y,axis=1)) #[[[1 2]], [[3 4]]] 相当于在第二层[]或第一层元素上加个[]
    print(np.expand_dims(y,axis=2)) #[[[1],[2]],[[3],[4]]] 相当于在第三层[]或第二层元素上加个[]
    #---------------------------------------------------------------
    
    # NumPy 字符串函数,用于对 dtype 为 numpy.string_ 或 numpy.unicode_ 的数组执行向量化字符串操作。
    #     add()    对两个数组的逐个字符串元素进行连接
    #     multiply()    返回按元素多重连接后的字符串
    #     center()    居中字符串
    #     capitalize()    将字符串第一个字母转换为大写
    #     title()    将字符串的每个单词的第一个字母转换为大写
    #     lower()    数组元素转换为小写
    #     upper()    数组元素转换为大写
    #     split()    指定分隔符对字符串进行分割,并返回数组列表
    #     splitlines()    返回元素中的行列表,以换行符分割
    #     strip()    移除元素开头或者结尾处的特定字符
    #     join()    通过指定分隔符来连接数组中的元素
    #     replace()    使用新字符串替换字符串中的所有子字符串
    #     decode()    数组元素依次调用str.decode
    #     encode()    数组元素依次调用str.encode
    
    #NumPy 中包含了一个矩阵库 numpy.matlib,该模块中的函数返回的是一个矩阵,而不是 ndarray 对象。
    #numpy.matlib库不在init内,需要import numpy.matlib
    
    # NumPy 提供了线性代数函数库 linalg,该库包含了线性代数所需的所有功能
    #     dot            两个数组的点积,即元素对应相乘。
    #     vdot            两个向量的点积
    #     inner            两个数组的内积
    #     matmul        两个数组的矩阵积
    #     determinant    数组的行列式
    #     solve            求解线性矩阵方程
    #     inv            计算矩阵的乘法逆矩阵
    
    # Numpy广播的规则可理解成:结构相同,点对点;结果不同,分别匹配。[]是最小单元,按最小单元匹配。
    # Numpy中逻辑尽量用逻辑操作运算符&/|,少用关键字and/or
    # Numpy的向量化操作比纯Python速度更快。
  • 相关阅读:
    DB设计原则
    英文地址[转]
    ICollection
    雅虎优化14条
    vue过滤器
    php中echo(),print(),print_r()之间的区别
    jQ中对attr()方法的理解
    浅析call和apply的不同
    浅析call和apply
    PHP是弱类型语言,自动转换,强制转换
  • 原文地址:https://www.cnblogs.com/i201102053/p/10878454.html
Copyright © 2011-2022 走看看