美文网首页Numpy
Numpy基础一

Numpy基础一

作者: __豆约翰__ | 来源:发表于2019-01-20 10:44 被阅读27次

    Numpy(Numerical Python的简称)是高性能科学计算和数据分析的基础包。它是我们课程所介绍的其他高级工具的构建基础。

    其部分功能如下:

    • ndarray, 一个具有复杂广播能力的快速且节省空间的多维数组。
    • 对于整组数据进行快速的运算,无需编写循环。
    • 用于读写磁盘数据的工具以及用于操作内容映射文件的工具。
    • 用于集成由C, C++等语言编写的代码的工具。

    Numpy本身并没有提供那么多高级的数据分析功能,理解Numpy数组以及面向数组的计算将有助于我们更加高效的使用pandas之类的工具。

    2.1 创建数组


    2.1.1 ndarray概述

    Numpy最重要的一个特点就是其N纬数组对象(即ndarray),该对象是一个快速而灵活的大数据集容器。你可以利用这种数组对整块的数据执行一些数学运算。

    ndarray是一个通用的同构数据多维容器,其中的所有元素必须是相同类型的。每个数组都有一个shape(表示各维度大小的元组)和一个dtype(表示数组数据类型的对象):

    我们将会介绍Numpy数组的基本用法,虽然说大多数数据分析工作不需要深入理解Numpy,但精通面向数组的编程和思维方式是成为Python科学计算牛人的一大关键步骤。

    注意: 我们将依照标准的Numpy约定,即总是使用import numpy as np. 当然你也可以为了不写np,而直接在代码中使用from numpy import *, 但是建议你最好还是不要养成这样的坏习惯。

    2.1.2 创建ndarray

    创建数组最简单的方法就是使用array函数。它接收一切序列型的对象(包括其他数组),然后产生一个新的含有传入数据的Numpy数组。

    1. array函数创建数组

    import numpy as np
    
    ndarray1 = np.array([1, 2, 3, 4])
    ndarray2 = np.array(list('abcdefg'))
    ndarray3 = np.array([[11, 22, 33, 44], [10, 20, 30, 40]])
    
    
    image.png

    2. zeros和zeros_like创建数组

    用于创建数组,数组元素默认值是0. 注意:zeros_linke函数只是根据传入的ndarray数组的shape来创建所有元素为0的数组,并不是拷贝源数组中的数据.

    ndarray4 = np.zeros(10)
    ndarray5 = np.zeros((3, 3))
    ndarray6 = np.zeros_like(ndarray5)  # 按照 ndarray5 的shape创建数组
    # 打印数组元素类型
    print("以下为数组类型:")
    print('ndarray4:', type(ndarray4))
    print('ndarray5:', type(ndarray5))
    print('ndarray6:', type(ndarray6))
    print("-------------")
    print("以下为数组元素类型:")
    print('ndarray4:', ndarray4.dtype)
    print('ndarray5:', ndarray5.dtype)
    print('ndarray6:', ndarray6.dtype)
    print("-------------")
    print("以下为数组形状:")
    print('ndarray4:', ndarray4.shape)
    print('ndarray5:', ndarray5.shape)
    print('ndarray6:', ndarray6.shape)
    
    
    image.png

    3. ones和ones_like创建数组

    用于创建所有元素都为1的数组.ones_like用法同zeros_like用法.

    # 创建数组,元素默认值是0
    ndarray7 = np.ones(10)
    ndarray8 = np.ones((3, 3))
    # 修改元素的值
    ndarray8[0][1] = 999
    ndarray9 = np.ones_like(ndarray5)  # 按照 ndarray5 的shape创建数组
    
    
    image.png

    4. empty和empty_like创建数组

    用于创建空数组,空数据中的值并不为0,而是未初始化的随机值.

    ndarray10 = np.empty(5)
    ndarray11 = np.empty((2, 3))
    ndarray12 = np.empty_like(ndarray11)
    
    
    image.png

    5. arange创建数组

    arange函数是python内置函数range函数的数组版本.

    # 产生0-9共10个元素
    ndarray13 = np.arange(10)
    # 产生从10-19共10个元素
    ndarray14 = np.arange(10, 20)
    # 产生10 12 14 16 18, 2为step
    ndarray15 = np.arange(10, 20, 2)
    # ndarray15的形状
    print('ndarray14的形状:', ndarray14.shape)
    # 将其形状改变为(2, 5)
    ndarray14.reshape((2, 5))
    
    
    image.png

    6. eys创建对角矩阵数组

    该函数用于创建一个N*N的矩阵,对角线为1,其余为0.

    ndarray16 = np.eye(5)
    
    
    image.png

    2.2 数据类型


    我们可以通过ndarray的dtype来打印数组中元素的类型. ndarray常见的数据类型如下:

    类型 类型代码 说明
    int8、uint8 i1、u1 有符号和无符号的8位(1个字节长度)整型
    int16、uint16 i2、u2 有符号和无符号的16位(2个字节长度)整型
    int32、uint32 i4、u4 有符号和无符号的32位(4个字节长度)整型
    float16 f2 半精度浮点数
    float32 f4或f 标准单精度浮点数
    float64 f8或d 双精度浮点数
    bool ? 布尔类型
    object O Python对象类型
    unicode_ U 固定长度的unicode类型,跟字符串定义方式一样
    import numpy as np
    
    ndarray1 = np.array([1, 2, 3, 4])
    ndarray2 = np.array(list('abcdefg'))
    ndarray3 = np.array([True, False, False, True])
    class Person(object):
        pass
    ndarray4 = np.array([Person(), Person(), Person()])
    
    
    image.png

    使用astype函数转换数组类型

    ndarray5 = np.array([1, 2, 3, 4, 5])
    # 类型转换完毕返回新的数组
    ndarray6 = ndarray5.astype(np.float32)
    
    # 如果浮点数转换为整数,则小数部分将会被截断
    ndarray7 = np.array([1.1, 2.2, 3.3, 4.4])
    ndarray8 = ndarray7.astype(np.int32)
    
    # 如果某些字符串数组表示的全是数字,也可以用astype将其转换为数值类型
    ndarray9 = np.array(['10', '20', '30', '40'])
    ndarray10 = ndarray9.astype(np.int32)
    
    
    image.png

    2.3 数组运算


    不需要循环即可对数据进行批量运算,叫做矢量化运算. 不同形状的数组之间的算数运算,叫做广播.

    import numpy as np
    
    ndarray1 = np.array([1, 2, 3, 4, 5])
    ndarray2 = np.array([3, 4, 5, 6, 7])
    
    # 数组和数组之间的运算
    ndarray3 = ndarray1 * ndarray2
    ndarray4 = ndarray1 + ndarray2
    
    # 数组和数字值之间的运算
    ndarray5 = ndarray1 + 100
    ndarray6 = 5 / ndarray1
    
    # 多维数组和多维数组之间的运算
    ndarray7 = np.arange(9).reshape((3, 3))
    ndarray8 = np.arange(9).reshape((3, 3))
    ndarray9 = ndarray7 + ndarray8 
    
    # 一维数组和多维数组之间运算
    ndarray10 = np.arange(3)
    ndarray11 = np.arange(6).reshape((2, 3))
    ndarray12 = ndarray10 + ndarray11
    
    
    image.png

    Numpy数组的索引是一个内容丰富的主题,因为选取数据子集或单个元素的方式有很多。一维数组很简单。从表面上看,它们和Python列表的功能差不多。

    2.4.1 数组索引和切片基本用法

    import numpy as np
    
    ndarray1 = np.arange(10)
    ndarray2 = np.arange(15).reshape((3, 5))
    
    
    image.png

    注意:

    1. 当把一个数字值赋值给一个切片时,该值会自动传播到整个选区。跟列表的区别在于,数组切片是原始数组的视图,这意味着数据不会被赋值,视图上的任何修改都会直接反应到源数组上.
    2. 大家可能对此感到不解,由于Numpy被设计的目的是处理大数据,如果Numpy将数据复制来复制去的话会产生何等的性能和内存问题.
    3. 如果要得到一个切片副本的话,必须显式进行复制操作.
    import numpy as np
    
    ndarray1 = np.arange(10)
    print('ndarray1->', ndarray1)
    print('ndarray1[3]->', ndarray1[3])
    print('ndarray1[3]->', ndarray1[2:5])
    print('--------------------------')
    
    ndarray2 = np.arange(15).reshape((3, 5))
    print('ndarray2->')
    print(ndarray2)
    print('ndarray2[2][1] ->', ndarray2[2][1]) 
    print('ndarray2[2, 1]->', ndarray2[2, 1])
    print('ndarray2[:2][:1]-> ', ndarray2[:2][:1])
    print('ndarray2[:2, :2]-> ')
    print(ndarray2[:2, :2])
    print('ndarray2[2, 1:3]-> ', ndarray2[2, 1:3])
    print('ndarray2[:2, 1]-> ', ndarray2[:2, 1])
    
    
    image.png

    提示

    ndarray2[:2][:1]->  [[0 1 2 3 4]]
    ndarray2[:2] ->[[0 1 2 3 4]
     [5 6 7 8 9]]
    ndarray2[:2][0:1]-> [[0 1 2 3 4]]
    

    2.4.2 数组花式索引

    import numpy as np
    ndarray1 = np.empty((8, 4))
    for i in range(8):
        ndarray1[i] = np.arange(i, i + 4)
    
    # 选取特定的子集,参数为列表
    ret1 = ndarray1[[0, 1, 6, 7]]
    
    # 使用负数索引会从末尾开始选取行
    ret2 = ndarray1[[-1, 0, -2]]
    
    # 一次传入多个数组
    ret3 = ndarray1[[1, 3, 5], [1, 2, 3]]
    ret4 = ndarray1[[1, 3, 5]][[1, 2]]
    
    # 获取选区数据
    ret5 = ndarray1[[1, 3, 5]][:, [1, 2, 3]]
    ret6 = ndarray1[np.ix_([1, 2, 4], [1, 2, 3])]
    
    
    image.png

    2.4.3 布尔型索引

    1. 布尔类型基本用法:
    import numpy as np
    
    names = np.array(['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff', 'ggg'])
    data = np.arange(35).reshape((7, 5))
    # 数组中每一个元素都进行==运算,返回一个数组
    mask = names == 'aaa'
    
    
    image.png
    2. 布尔类型数组跟切片、整数混合使用
    import numpy as np
    
    names = np.array(['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff', 'ggg'])
    data = np.arange(35).reshape((7, 5))
    
    ret1 = data[names == 'ccc']
    
    # 布尔类型数组和整数混合使用
    ret2= data[names == 'ccc', 2]
    
    # 布尔类型数组和切片混合使用
    ret3= data[names == 'ccc', 1:]
    
    
    image.png
    3. 使用不等于!=,使用(~)对条件否定
    import numpy as np
    
    names = np.array(['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff', 'ggg'])
    data = np.arange(35).reshape((7, 5))
    
    ret1 = data[names != 'ccc']
    ret2 = data[~(names == 'ccc')]
    ret3 = data[~(names > 'ccc')]
    
    
    image.png
    4. 使用&(和)、|(或)组合多个布尔条件

    注意: Python的关键字and、or在布尔数组中无效, 不能用来组合多个条件.

    import numpy as np
    
    names = np.array(['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff', 'ggg'])
    data = np.arange(35).reshape((7, 5))
    
    # 注意,Python的关键字and、or在布尔数组中无效
    ret1 = data[(names == 'aaa') | (names == 'ccc')]
    ret2 = data[(names > 'ddd') | (names == 'aaa')]
    ret3 = data[(names < 'eee') & (names > 'bbb') ]
    
    
    image.png
    5. 使用布尔类型数组设置值是一种经常用到的手段
    import numpy as np
    
    ndarray1 = np.arange(5)
    ndarray2 = np.arange(16).reshape((4, 4))
    names = np.array(['aaa', 'bbb', 'ccc', 'ddd'])
    
    # 将数组ndarray1中所有大于5的元素设置成666
    ndarray1[ndarray1 > 2] = 8
    
    # 将ndarray2的aaa这一行所有的元素设置为0
    ndarray2[names == 'aaa'] = 0
    # 将ndarray2的bbb这一行2位置往后所有的元素设置为1
    ndarray2[names == 'bbb', 2:] = 1
    # 将ndarray2的ccc ddd这2行所有的元素设置为2
    ndarray2[(names == 'ccc') | (names == 'ddd')] = 2
    
    
    image.png
    6. np.where用法

    已知有两个数组: ndarray1 = np.array([6, 7, 8, 6, 8, 3, 4, 5, 8, 7]) ndarray2 = np.array([3, 5, 3, 7, 2, 1, 2, 2, 7, 4]) 以此对比数组中对应位置的值,取出大的值,组成新的数组.

    import numpy as np
    
    # 创建两个数组
    ndarray1 = np.array([6, 7, 8, 6, 8, 3, 4, 5, 8, 7])
    ndarray2 = np.array([3, 5, 3, 7, 2, 1, 2, 2, 7, 4])
    # 比较条件
    result1 = [ n1 if c else n2 for n1, n2, c in zip(ndarray1, ndarray2, ndarray1 > ndarray2) ]
    # 这里也可以使用numpy提供的where函数
    # 使用格式为: result = np.where(条件, 值1, 值2)
    result2 = np.where(ndarray1 > ndarray2, ndarray1, ndarray2)
    
    
    image.png

    课堂小练习:

    • 已知数组: ndarray3 = np.arange(32).reshape((8, 4)) 8行4列元素数组.元素从左向右从上至下依次0~31.
    • 将数组中所有大于20的元素,替换为666.
    • 将数组中所有大于13, 并且小于17的元素替换为888.
    import numpy as np
    
    ndarray3 = np.arange(32).reshape((8, 4))
    # 将大于20的元素替换成666
    ret1 = np.where(ndarray3 > 20, 666, ndarray3)
    # 将大于13,并且小于17的元素替换成100
    ret2 = np.where(ndarray3 > 13, np.where(ndarray3 < 17, 100, ndarray3), ndarray3)
    
    
    image.png

    相关文章

      网友评论

        本文标题:Numpy基础一

        本文链接:https://www.haomeiwen.com/subject/vycndqtx.html