• 数据分析


    numpy

    概述

    ▨  Numerical Python. 补充了python所欠缺的数值计算能力

    ▨  Numpy是其他数据分析及机器学习库的底层库

    ▨  Numpy完全标准C语言实现,运行效率充分优化

    ▨  Numpy开源免费

    基本数据结构

    类型名类型表示符
    布尔类型 bool_
    有符号整型 int8/16/32/64
    无符号整型 uint8/16/32/64
    浮点型 float16/32/64
    复数型 complex64/128
    字符串型 str_,每个字符32位Unicode

     可见是不允许存储特殊对象类型的, 因为 numpy 的目标主要是处理数字类型的

    自定义复合类型

    基础的数据类型无法满足需求, 我就是想传入复杂数据

    方式一 - 直接设置

    取元素只能通过索引 [n] 的形式去取

    或者基于 默认别名 'fn' 的形式 ( n 依旧是索引下标 )

    import numpy as np
    
    data = [('zs', [90, 80, 70], 15),
            ('ls', [99, 89, 79], 16),
            ('ww', [91, 81, 71], 17)]
    
    # 2个Unicode字符,3个int32,1个int32组成的元组
    ary = np.array(data, dtype='U2, 3int32, int32')
    print(ary, ary.dtype) """ [('zs', [90, 80, 70], 15) ('ls', [99, 89, 79], 16) ('ww', [91, 81, 71], 17)] [('f0', '<U2'), ('f1', '<i4', (3,)), ('f2', '<i4')] """ print(ary[1][2], ary[1]['f2']) # 16 16

    方式二 - 带别名设置

    可以通过别名进行获取

    import numpy as np
    
    data = [('zs', [90, 80, 70], 15),
            ('ls', [99, 89, 79], 16),
            ('ww', [91, 81, 71], 17)]
    
    # 第二种设置dtype的方式  为每个字段起别名
    ary = np.array(data, dtype=[('name', 'str_', 2),  # 别名, 类型, 元素个数
                                ('scores', 'int32', 3),
                                ('age', 'int32', 1)])
    print(ary[2]['age']) # 17

    方式三 - 字典形式设置

    键值对形式相同位置简历映射, 

    name 键统一设置 别名

    formats 键统一设置 类型和数量

    是结合了一二两种方式的结果

    import numpy as np
    
    data = [('zs', [90, 80, 70], 15),
            ('ls', [99, 89, 79], 16),
            ('ww', [91, 81, 71], 17)]
    
    # 第三种设置dtype的方式
    ary = np.array(data, dtype={
        'names': ['name', 'scores', 'age'],
        'formats': ['U2', '3int32', 'int32']})
    print(ary[2]['scores']) # [91 81 71]

    方式四 - 字节方式设置

    依旧是字典格式

    使用别名作为 键

    值 为 元组形式

    ( '数量类型', 定位字节起点 )

    可以手动指定每个字段的存储偏移量

    举栗子

    ('U3',0)   Unicode 字符是32 位, 占4字节, 三个占位 12字节, 在 12 字节处结束

    ('3int32', 16)  定位在 16 字节处 , 即距离上面的又空了 4 字节, 然后 又是占位 12字节 , 在 28 字节处结束

    ('int32', 28)  定位在 28 字节处, 占位 12 字节, 在 40 字节处结束

    import numpy as np
    
    data = [('zs', [90, 80, 70], 15),
            ('ls', [99, 89, 79], 16),
            ('ww', [91, 81, 71], 17)]
    
    # 第四种设置dtype的方式 手动指定每个字段的存储偏移字节数
    # name从0字节开始输出,输出3个Unicode
    # scores从16字节开始输出,输出3个int32
    ary = np.array(data, dtype={
        'name': ('U3', 0),
        'scores': ('3int32', 16),
        'age': ('int32', 28)})
    print(ary[0]['name']) # zs

    存储日期类型数据

    只能识别 YYYY-MM-DD HH:MM:SS 的格式 , - 换成 / 就不行

    可以进行一定程度的运算

    # ndarray数组中存储日期类型数据
    dates = np.array(['2011', '2012-01-01', '2013-01-01 11:11:11', '2011-02-01'])
    print(dates, dates.dtype)
    # ['2011' '2012-01-01' '2013-01-01 11:11:11' '2011-02-01'] <U19
    
    dates = dates.astype('M8[D]')  # datetime64 精确到 Day
    
    print(dates, dates.dtype)
    # ['2011-01-01' '2012-01-01' '2013-01-01' '2011-02-01'] datetime64[D]
    
    print(dates[-1] - dates[0])  # 31 days
    
    dates = dates.astype('int32')
    print(dates, dates.dtype)  # [14975 15340 15706 15006] int32

    类型字符码 - 数据类型的简写

    类型字符码
    bool_ ?
    int8/16/32/64 i1/2/4/8
    uint8/16/32/64 u1/2/4/8
    float16/32/64 f2/4/8
    complex64/128 c8/16
    str_ U
    datetime64 M8[Y/M/D/h/m/s]

    数组 -  nadarray 对象

    概念

    类似于列表, 可以多维嵌套, 但是要求必须内部存储相同类型的数据

    即同质数组, 相同的数据类型的空间占用相同, 且查询方便

    空间结构

    ary = np.array([1, 2, 3, 4, 5])
    """         
               _______________________________________
    a  ----->  | nadarray 对象                         |
               |                                      |
               | 元数据                                |
               |_______                               |                 
               |_dim___|                              |  
               |_dtype_|        _____________________ |
               |_data__|   ---> |_1_|_2_|_3_|_4_|_5_| | 
               |_shape_|  ---> (5,)                   |
               |_______|______________________________|
    
    """

    元数据 (metadata)

    存储对数组的描述信息, 如 : dim count, dtype, dara, shape 等

    实际数据

    完整的数组数据, 将实际数据与元数据分开存放

    一方面提高了内存空间的使用效率

    另一方面减少对实际数据的访问频率,提高性能。

    创建语法

    np.array([[], [], []])  # 直接创建
    
    np.arange(0, 10, 1) # 序列创建
    
    np.zeros(10) # 全 0 创建
    
    np.ones(10) # 全 1 创建
    
    np.zeros_like(ary) # 仿结构创建 全 0 数组
    
    np.ones_like(ary) # 仿结构创建 全 1 数组

    示例

    import numpy as np
    
    a = np.array([1, 2, 3, 4, 5, 6])
    print(a)  # [1 2 3 4 5 6]
    
    b = np.arange(7, 13, 1)
    print(b)  # [ 7  8  9 10 11 12]
    
    c = np.zeros(6)
    print(c)  # [ 0.  0.  0.  0.  0.  0.]
    
    d = np.ones(6)
    print(d)  # [ 1.  1.  1.  1.  1.  1.]
    print(d / 2)  # [ 0.5  0.5  0.5  0.5  0.5  0.5]
    
    e = np.array([[1, 2, 3], [4, 5, 6]])
    print(np.ones_like(e))
    """
    [[1 1 1]
     [1 1 1]]
    """

    nadarray 对象属性 - 基本操作

    数组维度

    ary.shape   数组维度

    可以直接进行更改数组结构

    但是更改需要合理, 比如 6 元素 更改为 3*3 需要9元素则无法满足从而报错

    ary = np.array([1, 2, 3, 4, 5, 6])
    print(ary, ary.shape)  # [1 2 3 4 5 6] (6,)
    ary.shape = (2, 3) print(ary, ary.shape) """ [[1 2 3] [4 5 6]] (2, 3) """ print(ary[1][1]) # 5

    元素类型

    ary.dtype  数组元素类型

    ary.astype  修改元素类型

    数据类型直接更改是不可取的, 需要使用 astype 方法进行更改

    利用重新开辟新的空间来赋值存储

    即此方法不会改变原值, 需要用返回值进行复制

    # 数组元素类型
    ary = np.array([1, 2, 3, 4, 5, 6])
    print(ary, ary.dtype)  # [1 2 3 4 5 6] int32
    # ary.dtype = np.int64 # print(ary, ary.dtype)
    # 更改数据类型 b = ary.astype('float32') print(ary, ary.dtype) # [1 2 3 4 5 6] int32 print(b, b.dtype) # [ 8.58993459e+09 1.71798692e+10 2.57698038e+10] float32

    数组元素个数

    ary.size  返回数组元素个数

    len(ary)  返回数组元素个数

    ary = np.array([1, 2, 3, 4, 5, 6])
    print(ary.size)  # 6
    print(len(ary))  # 6

    数组元素索引

    下标

    # 数组元素的索引
    ary = np.arange(1, 9)
    ary.shape = (2, 2, 2)
    print(ary, ary.shape)
    """
    [[[1 2]
      [3 4]]
    
     [[5 6]
      [7 8]]] (2, 2, 2)
    """
    
    print(ary[0])  # 0页数据
    """
    [[1 2]
     [3 4]]
    """
    
    print(ary[0][0])  # 0页0行数据
    """
    [1 2]
    """
    
    print(ary[0][0][0])  # 0页0行0列数据
    """
    1
    """
    
    print(ary[0, 0, 0])  # 0页0行0列数据
    """
    1
    """
    
    
    # 使用for循环,把ary数组中的元素都遍历出来。
    for i in range(ary.shape[0]):
        for j in range(ary.shape[1]):
            for k in range(ary.shape[2]):
                print(ary[i, j, k], end=' ')
    
    # 1 2 3 4 5 6 7 8 

    ndarray对象 - 维度操作详解

    视图变维  

    reshape() - 改变维度

    在原数据上建立的 映射,  即源数据的刚刚会影响其他视图的展示

    import numpy as np
    
    a = np.arange(1, 7)
    # print(a, a.shape)  # [1 2 3 4 5 6] (6,)
    
    # 测试视图变维 reshape()  ravel()
    b = a.reshape(2, 3)
    print(b, b.shape)
    """
    [[1 2 3]
     [4 5 6]] (2, 3)
    """
    
    a[0] = 999
    print(b, b.shape)
    """
    [[999   2   3]
     [  4   5   6]] (2, 3)
    """

    ravel() - 扁平化处理

    将高维度变为一维

    print(b, b.shape)
    """
    [[999   2   3]
     [  4   5   6]] (2, 3)
    """
    
    c = b.ravel()
    print(c, c.shape)
    # [999   2   3   4   5   6] (6,)

    总结

    视图变维是基于源文件的, 因此不会开辟新的内存空间

    ravel 的平铺可以简单的展开数组进行一维输出

    复制变维 

     flatten() - 扁平化处理

    使用方法和结果同 ravel 

    但是是重新开辟空间处理, 源数据与新数据是空间隔离互不干涉的

    import numpy as np
    
    # 复制变维  flatten()   copy()
    a = np.array([[1, 2, 3], [4, 5, 6]])
    
    b = a.flatten()  # 扁平化
    print(b, b.shape)  # [1 2 3 4 5 6] (6,)
    a[0] = 1
    print(a, a.shape)
    """
    [[1 1 1]
     [4 5 6]] (2, 3)
    """
    
    print(b, b.shape)  # [1 2 3 4 5 6] (6,)

    就地变维

    shape()

    resize()

    直接基于源数据的更改

    import numpy as np
    
    # 就地变维
    a = np.arange(1, 7)
    a.resize(3, 2)
    print(a, a.shape) """ [[1 2] [3 4] [5 6]] (3, 2) """

    ndarray对象 - 索引操作

    ndarray数组 - 切片

    [::]  / [:] 全部

    [m:n]  m到n 左包右不包 , 为负数表示倒数 m / n 位

    [::n]  步长

    [::-1]  倒序

    切片是会生成新的对象, 因此 直接使用 [::] 来代替复制是可以的

    """
    demo05_shape.py
    """
    import numpy as np
    
    a = np.arange(1, 10)
    print(a)  # [1 2 3 4 5 6 7 8 9]
    print(a[:3])  # [1 2 3]
    print(a[3:6])  # [4 5 6]
    print(a[6:])  # [7 8 9]
    print(a[::-1]) # [9 8 7 6 5 4 3 2 1] print(a[:-4:-1]) # [9 8 7] print(a[::]) # [1 2 3 4 5 6 7 8 9]
    print(a[::3]) # [3 6 9] print(a[1::3]) # [3 6 9] print(a[2::3]) # [3 6 9]

    高维切片

    [  行的切片 ,   列的切片   ]

    # 高维数组切片
    a = a.reshape(3, 3)
    print(a, a.shape)
    """
    [[1 2 3]
     [4 5 6]
     [7 8 9]] (3, 3)
    """
    
    print(a[:2, :2])
    """
    [[1 2]
     [4 5]]
    """
    
    print(a[:2, 0])
    """
    [1 4]
    """

    ndarray数组 - 掩码操作

    非常方便两个数组的重叠映射, 将 True 的元素输出

    import numpy as np
    
    a = np.arange(1, 8)
    mask = a > 5
    print(a)  # [1 2 3 4 5 6 7]
    print(mask)  # [False False False False False  True  True]
    print(a[mask])  # [6 7]

    此方法可以进行相当多的炫酷操作, 如下

    import numpy as np
    
    # 输出100以内3与7的公倍数。
    a = np.arange(1, 100)
    mask = (a % 3 == 0) & (a % 7 == 0)
    print(a[mask])  # [21 42 63 84]
    
    # 利用掩码运算对数组进行排序 p = np.array(['Mi', 'Apple', 'Huawei', 'Oppo']) r = [1, 3, 2, 0] print(p[r]) # ['Apple' 'Oppo' 'Huawei' 'Mi']

    多维数组 - 组合与拆分

    垂直方向操作

    vstack - 合并

    vsplit - 拆分

    垂直方向合并及列合并, 增加列

    拆分需要合理, 不合理的炒粉会报错 ( 5个拆成 4 个之类的 )

    # 垂直方向合并
    c = np.vstack((a, b))
    # 把c拆成2份, a与b a, b = np.vsplit(c, 2)
    import numpy
    
    a = numpy.array([1, 2, 3])
    b = numpy.array([4, 5, 6])
    
    c = numpy.vstack((a, b))
    # print(c)
    """
    [[1 2 3]
     [4 5 6]]
    """
    
    a, b = numpy.vsplit(c, 2)
    print(a)  # [[1 2 3]]
    print(b)  # [[4 5 6]]

    水平方向操作

    hstack - 合并

    hsplit - 拆分

    水平方向合并及行合并, 增加行长度

    拆分需要合理, 不合理的炒粉会报错 ( 5个拆成 4 个之类的 )

    # 水平方向合并
    c = np.hstack((a, b))
    # 把c拆成2份, a与b
    a, b = np.hsplit(c, 2)
    import numpy
    
    a = numpy.array([1, 2, 3])
    b = numpy.array([4, 5, 6])
    
    c = numpy.hstack((a, b))
    print(c)  # [1 2 3 4 5 6]
    
    a, b = numpy.hsplit(c, 2)
    print(a)  # [1 2 3]
    print(b)  # [4 5 6]

    深度方向操作

    dstack - 合并

    dsplit - 拆分

    深度方向合并即维度合并, 增加维度

    拆分需要合理, 不合理的炒粉会报错 ( 比如拆 3 份 )

    # 深度方向合并
    c = np.dstack((a, b))
    # 把c拆成2份, a与b
    a, b = np.dsplit(c, 2)
    import numpy
    
    a = numpy.array([1, 2, 3])
    b = numpy.array([4, 5, 6])
    
    c = numpy.dstack((a, b))
    print(c)
    """
    [[[1 4]
      [2 5]
      [3 6]]]
    """
    
    a, b = numpy.dsplit(c, 2)
    print(a)  
    """
    [[[1]
      [2]
      [3]]]
    """
    print(b)  
    """
    [[[4]
      [5]
      [6]]]
    """
    import numpy
    
    a = numpy.array([[1, 2, 3], [4, 5, 6]])
    b = numpy.array([[7, 8, 9], [10, 11, 12]])
    
    c = numpy.dstack((a, b))
    # print(c)
    """
    [[[ 1  7]
      [ 2  8]
      [ 3  9]]
    
     [[ 4 10]
      [ 5 11]
      [ 6 12]]]
    """
    
    a, b = numpy.dsplit(c, 2)
    # print(a)
    """
    [[[1]
      [2]
      [3]]
    
     [[4]
      [5]
      [6]]]
    """
    
    # print(b)
    """
    [[[ 7]
      [ 8]
      [ 9]]
    
     [[10]
      [11]
      [12]]]
    """

    多维数组 - 组合与拆分相关函数

    concatenate( ) -  组合

    split ()  -  拆分

    # 把a与b按照axis的轴向进行组合
    # axis 数组组合的轴向 # 0:垂直 1:水平 2:深度 # 注意:若axis=2,则要求a与b都是3维数组
    c = np.concatenate((a, b), axis=0)
    # 把c按照axis的轴向拆成2部分 a, b = np.split(c, 2, axis=0)

    简单的一维数组的组合方案

    row_stack - 行合并

    column_stack - 列合并

    # 把两个一维数组摞在一起成两行
    c = np.row_stack((a, b))
    # 把两个一维数组并在一起成两列
    c = np.column_stack((a, b))
    import numpy
    
    a = numpy.array([1, 2, 3, 4, 5, 6])
    b = numpy.array([7, 8, 9, 10, 11, 12])
    
    c = numpy.row_stack((a, b))
    print(c)
    """
    [[ 1  2  3  4  5  6]
     [ 7  8  9 10 11 12]]
    """
    
    d = numpy.column_stack((a, b))
    print(d)
    """
    [[ 1  7]
     [ 2  8]
     [ 3  9]
     [ 4 10]
     [ 5 11]
     [ 6 12]]
    """

    ndarray数组 - 其他属性

      ▨ shape, dtype, size ....

      ▨ ndim   维数 n维数组的那个n

      ▨ itemsize   每个元素的字节数

      ▨ nbytes   数组占用内存的总字节数

      ▨ real   复数数组的数据的实部

      ▨ imag   复数数组的数据的虚部

      ▨ T   返回数组的转置视图

      ▨ flat   返回数组的扁平迭代器

    """
    demo09_attr.py 其他属性
    """
    import numpy as np
    
    data = np.array([[1 + 1j, 2 + 4j, 3 + 7j],
                     [4 + 2j, 5 + 5j, 6 + 8j],
                     [7 + 3j, 8 + 6j, 9 + 9j]])
    print(data.ndim)  # 2
    print(data.dtype, data.itemsize)  # complex128 16
    print(data.nbytes)  # 144
    print(data.real)
    """
    [[ 1.  2.  3.]
     [ 4.  5.  6.]
     [ 7.  8.  9.]]
    """
    print(data.imag) """ [[ 1. 4. 7.] [ 2. 5. 8.] [ 3. 6. 9.]] """ print(data.T) """ [[ 1.+1.j 4.+2.j 7.+3.j] [ 2.+4.j 5.+5.j 8.+6.j] [ 3.+7.j 6.+8.j 9.+9.j]] """ print([x for x in data.flat]) # [(1+1j), (2+4j), (3+7j), (4+2j), (5+5j), (6+8j), (7+3j), (8+6j), (9+9j)]
  • 相关阅读:
    IO流
    泛型类
    自动打包&解包:auto-boxing&unboxing
    Map接口
    如何选择数据结构
    Compareable接口
    List常用算法
    equals和==
    List接口
    set接口
  • 原文地址:https://www.cnblogs.com/shijieli/p/10846772.html
Copyright © 2020-2023  润新知