zoukankan      html  css  js  c++  java
  • numpy---python数据分析

    在这里插入图片描述

    最后大图可点开保存

    学习目标

    • 目标
      • 了解Numpy运算速度上的优势
      • 知道Numpy的数组内存块风格
      • 知道Numpy的并行优化运算
    • 应用
      • 机器学习,深度学习各种框架的基础库
    • 内容预览
      • 3.1.1 Numpy介绍
      • 3.1.2 ndarray介绍
      • 3.1.3 ndarray与python原生list运算效率对比
      • 3.1.4 ndarray的优势

    3.1.1Numpy介绍

    num - numerical
    py - python
    numpy - numerical python
    Numpy是一个开源的Python科学计算库,用于快速处理任意维度的数组。
    Numpy使用ndarray对象来处理多维数组,该对象是一个快速而灵活的大数据容器
    ndarray:
    n - 任意个
    d - dimension 维度
    array - 数组
    

    3.1.2 ndarray介绍

    Numpy提供了一个N维数组类型ndarray,它描述了相同类型的"items"的集合。
    在这里插入图片描述
    使用ndarray进行存储:

    import numpy as np
    
    # 创建ndarray
    score = np.array([[80, 89, 86, 67, 79],
                     [78, 97, 89, 67, 81],
                     [90, 94, 78, 67, 74],
                     [91, 91, 90, 67, 69],
                     [76, 87, 75, 67, 86],
                     [70, 79, 84, 67, 84],
                     [94, 92, 93, 67, 84],
                     [86, 85, 83, 67, 80]])
    

    使用Python列表可以存储一维数组,通过列表的嵌套可以实现多维数组,那么为什么还需要使用Numpy的ndarray呢?

    3.1.3 ndarray与Python原生list运算效率对比

    import random
    import time
    import numpy as np
    
    
    a = []
    for i in range(100000000):  # 随机生成一亿个数字
        a.append(random.random())
    t1 = time.time()
    sum1 = sum(a)
    t2 = time.time()
    
    b = np.array(a)
    t4 = time.time()
    sum2 = np.sum(b)
    t5 = time.time()
    print(t2-t1, t5-t4)
     # 0.9411723613739014   0.18763375282287598
    

    从中我们可以看出ndarray的计算速度要快很多,节约了时间。

    机器学习的最大特点:就是大量的数据运算,那么如果没有一个快速的解决方案,那可能现在python也在机器学习领域达不到好的效果。

    3.1.4 ndarray的优势

    • 内存块存储风格

    ndarray ; 元素相同类型 ; 通用性不强, 元素在内存中连续。

    list ; 元素不同类型 ; 通用性很强, 元素在内存中不一定连续,如列表中还有个字典

    • 并行化运算(向量化运算)

    不需要循环,直接向量化运算,同时计算。

    • 底层语言

    Numpy底层使用C语言编写,内部解除了GIL(全局解释器锁),其对数组的操作速度不受Python解释器的限制,效率远高于纯Python代码。

    3.2 认识N维数组 -ndarray属性

    3.2.1 ndarray的属性

    数组属性反映了数组本身固有的信息:

    属性名字 属性解释
    ndarray.shape 数组维度的元组
    ndarray.ndim 数组维数
    ndarray.size 数组中的元素数量
    ndarray.dtype 数组元素的类型
    ndarray.itemsize 一个数组元素的长度(字节)

    最重要的两个属性是shapedtype

    当我们知道了形状shap即维度的时候,我们就可以知道维数ndim、数组的元素个数(数组大小)size

    当我们知道数组中的元素的类型的时候,我们就可以知道一个数组元素的长度itemsize,因为不同类型的元素在内存中的占用是固定的。

    示例:

    score = np.array([[80, 89, 86, 67, 79],
                     [78, 97, 89, 67, 81],
                     [90, 94, 78, 67, 74],
                     [91, 91, 90, 67, 69],
                     [76, 87, 75, 67, 86],
                     [70, 79, 84, 67, 84],
                     [94, 92, 93, 67, 84],
                     [86, 85, 83, 67, 80]])
    # 整个数组
    print(score.shape)  # (8, 5) 
    print(score.ndim)  # 2  二维
    print(score.size)  # 40  数组元素个数
    # 单个元素
    print(score.dtype)  # int32 元素的类型
    print(score.itemsize) # 4  元素大小
    

    3.2.2 ndarray的形状

    a = np.array([[1, 2, 3], [4, 5, 6]])
    a.shape  # (2, 3)
    
    b = np.array([1, 2, 3, 4])
    b.shape  # (4, )
    
    c = np.array([[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]])
    c.shape  # (2, 2, 3)
    # shape先看第一个中括号内几个部分,再看第二个中括号....
    

    3.2.3 ndarray元素类型

    • 默认:
      • 整数 int64
      • 小数 float64
    • 创建数组的时候指定类型
    np.array([1.1, 1.2, 1.3], dtype="float32")
    np.array([1.1, 1.2, 1.3], dtype=float32)
    # 两种方式是等价的
    

    3.3 基本操作

    学习目标

    • 目标
      • 理解数组的各种生成方法;
      • 应用数组的索引机制实现数组的切片获取
      • 应用维度变换实现数组的形状改变
      • 应用类型变换实现数组类型改变
      • 应用数组的转换
    • 应用
      • 应用正态分布实现模拟股票的涨跌幅数据操作
    • 内容预览
      • 3.3.1 生成数组的方法
        • 1 生成0和1的数组
        • 2 从现有数组生成
        • 3 生成固定范围的数组
        • 4 生成随机数组
      • 3.3.2 数组的索引、切片
      • 3.3.3 形状修改
      • 3.3.4 类型修改
      • 3.3.5 数组的去重

    3.3.1 生成数组的方法

    1 生成0和1的数组

    生成这样的数组的方式有很多,没有必要全都记住,这里推荐ones方法和zeros方法:

    np.zeros(shape=(3, 4), dtype="float32")
    np.ones(shape=[2, 3], dtype=int32)
    # 列表和元素表示都可以
    

    2从现有数组中生成

    有array、asarray、copy几种方法:

    score = np.array([[80, 89, 86, 67, 79],
                     [78, 97, 89, 67, 81],
                     [90, 94, 78, 67, 74],
                     [91, 91, 90, 67, 69],
                     [76, 87, 75, 67, 86],
                     [70, 79, 84, 67, 84],
                     [94, 92, 93, 67, 84],
                     [86, 85, 83, 67, 80]])
                     
    data1 = np.array(score)
    print(data1)
    '''array([[80, 89, 86, 67, 79],
                     [78, 97, 89, 67, 81],
                     [90, 94, 78, 67, 74],
                     [91, 91, 90, 67, 69],
                     [76, 87, 75, 67, 86],
                     [70, 79, 84, 67, 84],
                     [94, 92, 93, 67, 84],
                     [86, 85, 83, 67, 80]])'''
    
    data2 = np.asarray(score)
    print(data2)
    '''array([[80, 89, 86, 67, 79],
                     [78, 97, 89, 67, 81],
                     [90, 94, 78, 67, 74],
                     [91, 91, 90, 67, 69],
                     [76, 87, 75, 67, 86],
                     [70, 79, 84, 67, 84],
                     [94, 92, 93, 67, 84],
                     [86, 85, 83, 67, 80]])'''
                     
    data2 = np.copy(score)
    print(data2)
    '''array([[80, 89, 86, 67, 79],
                     [78, 97, 89, 67, 81],
                     [90, 94, 78, 67, 74],
                     [91, 91, 90, 67, 69],
                     [76, 87, 75, 67, 86],
                     [70, 79, 84, 67, 84],
                     [94, 92, 93, 67, 84],
                     [86, 85, 83, 67, 80]])'''
    
    

    但是这三个是有区别的:array和copy是深拷贝; asarray是浅拷贝。

    3生成固定范围的数组

    有np.linspace()和np.arange()方法;

    • np.linspace(0, 10, 100)
      生成[0, 10]等距离的100个
    data = np.linspace(0, 10, 6)  # 等分生成6个
    print(data)
    # [ 0.  2.  4.  6.  8. 10.]
    
    • np.arange(a, b, c)
      和range是一样的
    data2 = np.arange(0, 10, 6) # 步长是6
    print(data2)  # [0, 6]
    

    生成随机数

    • np.random
    • np.random.uniform(low=0, high=1, size=None)
    • 均匀分布(Uniform Distribution)
      是概率论统计中的重要分布之一。顾名思义,均匀,表示可能性相等的含义。均匀分布在自然情况下极为罕见,而人工栽培的有一定株行距的植物群落是均匀分布。
    # 生成均匀分布的随机数
    x1 = np.random.uniform(-1, 1, 1000)
    
    # 返回结果
    print(x1)
    [ 0.56347276 -0.94591979 -0.23197083  ... -0.79391627 -0.32959637]
    
    
    # 这里用直方图来表示这个均匀分布
    import matplotlib.pyplot as plt
    
    # 1. 创建画布
    plt.figure(figseze=(20, 8), dpi=80)
    
    # 2. 绘制直方图
    plt.hist(x1, 1000)
    
    # 3. 显示图像
    plt.show()
    

    画出的直方图:
    在这里插入图片描述

    • 正态分布
      是具有两个参数μ和σ的连续型随机变量的分布,第一参数μ是服从正态分布的随机变量的均值,第二个参数σ是此随机变量的标准差,所以正态分布记作N(μ, σ).
      σ 幅度、波动程度、集中程度、稳定性
      μ决定图像的位置

    f(x) = (1 / σ(2π)0.5 ) e^((x-μ)**2) / 2 σ**2^

    方差:
    在这里插入图片描述
    标准差是s

    方差越小越稳定

    np.random.normal(loc=0.0, scale=1.0, size=None)
    loc是均值, scale是标准差,对应图像的宽度

    data2 = np.random.normal(loc=1.75, scale=0.1, size=10000)
    print(data2)
    [1.55345983 1.73792734 1.62380419 ... 1.80401868 1.90379977 1.69976006]
    
    # 这里用直方图来表示这个正态分布
    import matplotlib.pyplot as plt
    
    # 1. 创建画布
    plt.figure(figseze=(20, 8), dpi=80)
    
    # 2. 绘制直方图
    plt.hist(data2, 10000)
    
    # 3. 显示图像
    plt.show()
    

    在这里插入图片描述

    案例:随机生成8只股票2周的交易日涨幅数据

    stock_change = np.random.normal(loc=0, scale=1, size=(8, 10))
    

    数组的索引、切片

    • 获取第一支股票的前3个交易日的涨跌幅数据
    # 二维数组,两个维度
    stock_change[0, 0:3]
    

    形状修改

    • 需求:让刚才的股票行、日期列反过来,变成日期行、股票列
    stock_change.reshape(10, 8) # 我们发现只是对数据进行了重新分割,并没有反转
    stock_change.resize(10, 8) # in-place, 没返回,并没有反转
    
    stock_change.T  # 转置,行变成列, 列变成行,有返回
    

    3.3.4 类型修改

    • ndarray.astype(type)
      如果想要序列化到本地,先要转成bytes类型
    stock_change.astype("int32")
    
    stock_change.tostring() # bytes类型
    

    扩展:
    jupyter对输出的字节数有限制,需要去修改配置文件, 但是不建议

    3. 3. 5 数组的去重

    temp = np.array([1, 2, 3, 4], [3, 4, 5, 6])
    np.unique(temp) # 返回array[1, 2, 3, 4, 5, 6]
    temp.flatten()  # 扁平化
    set(temp)
    

    3.3.6 小结

    • 创建数组
      • 均匀
      • 随机(正态分布)
    • 正太分布
    • 数组索引
    • 数组形状改变
    • 数组类型
      • reshape
      • resize
    • 数组转换
      • T
      • tostring
      • unique

    3.4 ndarray运算

    学习目标

    • 目标
      • 应用数组的通用判断函数
      • 应用np.where实现数组的三元运算
    • 应用
      • 股票涨跌幅数据逻辑运算
    • 内容预览
      • 3.4.1逻辑运算
      • 3.4.2通用判断函数
      • 3.4.3np.where(三元运算符)
      • 3.4.4统计运算

    问题

    如果想要操作符合某一条件的数据,应该怎么做?

    3.4.1逻辑运算

    # 重新生成8只股票10个交易日的涨跌幅数据
    stock_change = np.random.normal(0, 1, (8, 10)) # loc=0, 方差=1, 8行10列
    stock_change = stock_change[0:5, 0:5]  # 获取前五行的前五列
    
    # 逻辑判断,如果涨幅大于0.5就标记为True 否则为False
    stock_changes > 0.5  # 返回新的,bool
    stock_changes[stock_changes > 0.5] = 1.1  # 满足条件的统一处理
    
    

    3.4.2 通用判断函数

    • np.all()
      只有全是True才会返回True
    判断stock_changes[0:2, 0:5]是否全是上涨的
    np.all(stock_changes[0:2, 0:5] > 0)
    false
    
    • np.any()
      只要有一个True就会返回True
    # 判断前5只股票这段时间是否有上涨
    np.any(stock_changes[0:5, :] > 0)
    True
    

    3.4.3 np.where (三元运算符)

    通过使用np.where能够进行更加复杂的运算

    • np.where()
    # 判断前四只股票前四天的涨跌幅  大于0的置为1, 否则为0
    temp = stock_changes[:4, :4]
    np.where(temp > 0, 1, 0)
    
    • 复合逻辑需要结合np.logical_and和logical_or使用
    # 判断前四个股票前四天的涨跌幅  大于0.5并且小于1的, 换为1, 否则0
    # 判断前四个股票前四天的涨跌幅 大于0.5或者小于-0.5的, 换为1, 否则为0
    np.where(np.logical_and(temp > 0.5, temp < 1), 1, 0)
    np.where(np.logical_or(temp > 0.5, temp < -0.5), 1, 0)
    

    3.4.4 统计指标

    使用方法:np.函数名 ; ndarray.方法名

    • np.min(a[, axis, out, keepdims])

    • np.max(a[, axis, out, keepdims])

    • np.median(a[, axis, out, overwrite_input, keeepdims])

    • np.mean(a[, axis, dtype, out, keepdims])

    • np.std(a[, axis, dtype, out, ddof, keepdims])

    • np.var(a[, axis, dtype, out, ddof, keepdims])

    进行统计的时候,axis轴的取值并不一定,Numpy中不同的API轴的值不一样,在这里,axis 0 代表列, axis 1 代表行进行统计

    print("前四只股票前四天的最大涨幅{}".format(np.max(temp, axis=1)))
    print("前四只股票前四天的最大跌幅{}".format(np.min(temp, axis=1)))
    print("前四只股票前四天的波动程度{}".format(np.std(temp, axis=1)))
    print("前四只股票前四天的平均涨跌幅{}".format(np.mean(temp, axis=1)))
    
    np.argmax(temp, axis=1)  # 返回的是索引
    

    3.5 数组间的运算

    3.5.1 应用场景

    3.5.2 数组与数的运算

    arr = np.array([1, 2, 3, 4], [2, 3, 4, 5])
    arr + 1   # 每个元素加1  - 、 *、 / 都是可以的
    

    3.5.3 数组与数组的运算

    
    

    3.5.4 广播机制

    执行broadcast的前提在于, 两个ndarray执行的是element-wise的运算,Broadcast机制的功能是为了方便不同形状的ndarray进行数学运算。
    当操作两个数组时,numpy会逐个比较他们的shape(构成的元组tuple), 只有在下述情况下,两个数组才能够进行数组与数组的运算。

    • 维度相等
    • shape(其中相对应的一个地方为1)

    3.5.5 矩阵运算

    1 矩阵存储
    两种方法存储矩阵:

    1. matrix
    2. ndarray
    data = np.array([1, 2], [2, 4], [5, 6])
    data1 = np.mat([1, 2], [2, 4], [5, 6])
    

    2 矩阵乘法运算
    形状改变:
    m行n列 * n行任l列 = m行l 列

    矩阵乘法api

    • np.matmul
      mat是matrix; mul是multiply
    • np.dot
    np.matmul(a, b)
    np.dot(a, b)
    

    ndarray要用这两个进行乘法;如果是matrix直接 * 就可以了
    ndarray也可以用 @,ndarray * ndarray是检查广播机制

    3.6合并、分割的用处

    3.6.1 合并

    np.hstack(tup)
    np.vstack(tup)

    np.concatenate((a1, a2, …), axis=0) 0是竖直拼接; 1是水平拼接

    3.6.2 分割

    np.split(ary, indices_or_sections, axis=0)

    3.7 IO操作与数据处理

    学习目标

    • 目标
      • 知道Numpy文件的读取
    • 应用
    • 内容预览
      • 3.7.1 Numpy读取
      • 3.7.2 如何处理缺失值
        • 1 什么是缺失值
        • 2 缺失值处理
          问题
          大多数数据并不是我们自己创造的, 而是存在文件当中,需要我们用工具获取。
          但是Numpy其实并不适合用来读取和处理数据,因此我们这里了解相关API,以及Numpy不方便的地方即可。

    3.7.1 Numgy读取

    test = np.genfromtxt("test.csv", delimiter=",")
    

    3.7.2 如何处理缺失值

    1.什么是缺失值
    什么时候numpy中会出现nan:当我们读取本地的文件为float的时候,nan

    2 如何处理缺失值
    两种思路:
    - 直接删除
    - 替换/插补

    3.8总结

    在这里插入图片描述

  • 相关阅读:
    【高级内部资料】.NET数据批量写入性能分析 第二篇
    负载均衡原理与实践详解 第五篇 负载均衡时数据包流程详解
    负载均衡原理与实践详解 第三篇 服务器负载均衡的基本概念网络基础
    如何提高Linq查询的性能(上)
    【全面解析DeepZoom 之二】Silverlight2及Deep Zoom环境的搭建
    关于让WPF软件界面支持全球化和本地化
    在WPF中自定义控件(3) CustomControl (上)
    【全面解析DeepZoom 之一】酷!Deep Zoom
    谈谈我理解的WPF团队模型——在UI Designer与Developer之间
    [WPF疑难]在WPF中显示动态GIF
  • 原文地址:https://www.cnblogs.com/duanming/p/11830271.html
Copyright © 2011-2022 走看看