• 【Python数据科学快速入门系列 | 03】玩转数据摘取:Numpy的索引与切片


    这是机器未来的第41篇文章

    原文首发地址:https://blog.csdn.net/RobotFutures/article/details/126176343

    在这里插入图片描述

    1. 索引与切片

    numpy数据容器ndarray和list一样,同样支持索引和切片访问和修改。更多索引和切片基础知识详见之前的博文【Python数据容器之序列】

    在这里,我们使用sklearn自带的数据集——鸢尾花数据集来举例。

    # 导入鸢尾花数据集
    import numpy as np
    
    data = []
    with open(file='iris.txt',mode='r') as f:
        # 打印标题行
        print(f"title:{f.readline()}")
    
        # f.readlines()读取文件所有行
        for line in f.readlines():  # 每次取一行数据
            data.append(line.strip().split(','))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    title:sepal_length,sepal_width,petal_length,petal_width,target_names
    
    • 1
    # 从上面代码的执行结果可以看到,数据集有5个标题,对应5列数据
    # 前4列为鸢尾花的特征,最后1列为鸢尾花的分类
    # sepal_length - 花萼长度
    # sepal_width - 花萼宽度
    # petal_length - 花瓣长度
    # petal_width - 花萼宽度
    # target_names - 目标名称
    
    # 取2行数据,看一下数据值与类型
    data[:2]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    [['5.1', '3.5', '1.4', '0.2', '0'], ['4.9', '3.0', '1.4', '0.2', '0']]
    
    • 1
    # 从上面列表提取的前2行数据可以看到,它的数据类型为字符串,在将data从list转换为ndarray数组时,直接做数据类型转换,转换为float
    data = np.array(data, dtype=float)
    
    
    • 1
    • 2
    • 3
    # 和列表一样,ndarray对象也可以使用切片的方式访问数组
    # 这里提取前4行数据查看一下数据值的范围及数据类型
    data[:4]  
    
    • 1
    • 2
    • 3
    array([[5.1, 3.5, 1.4, 0.2, 0. ],
           [4.9, 3. , 1.4, 0.2, 0. ],
           [4.7, 3.2, 1.3, 0.2, 0. ],
           [4.6, 3.1, 1.5, 0.2, 0. ]])
    
    • 1
    • 2
    • 3
    • 4

    1.1 如何提取指定列的数据

    思考:在做数据预处理时可能会分析特征数据与标签数据的相关性,我们需要提取指定列的数据与标签数据做分析,那么如何提取某一列数据呢?
    使用切片来提取。先看一下数据的shape

    data.shape
    
    • 1
    (150, 5)
    
    • 1

    可以看到是150行,5列,现在需要提取第3列数据,可以这样操作

    # 逗号前的:表示提取全部行,逗号后的2表示提取第3列
    data[:,2]
    
    • 1
    • 2
    array([1.4, 1.4, 1.3, 1.5, 1.4, 1.7, 1.4, 1.5, 1.4, 1.5, 1.5, 1.6, 1.4,
           1.1, 1.2, 1.5, 1.3, 1.4, 1.7, 1.5, 1.7, 1.5, 1. , 1.7, 1.9, 1.6,
           1.6, 1.5, 1.4, 1.6, 1.6, 1.5, 1.5, 1.4, 1.5, 1.2, 1.3, 1.4, 1.3,
           1.5, 1.3, 1.3, 1.3, 1.6, 1.9, 1.4, 1.6, 1.4, 1.5, 1.4, 4.7, 4.5,
           4.9, 4. , 4.6, 4.5, 4.7, 3.3, 4.6, 3.9, 3.5, 4.2, 4. , 4.7, 3.6,
           4.4, 4.5, 4.1, 4.5, 3.9, 4.8, 4. , 4.9, 4.7, 4.3, 4.4, 4.8, 5. ,
           4.5, 3.5, 3.8, 3.7, 3.9, 5.1, 4.5, 4.5, 4.7, 4.4, 4.1, 4. , 4.4,
           4.6, 4. , 3.3, 4.2, 4.2, 4.2, 4.3, 3. , 4.1, 6. , 5.1, 5.9, 5.6,
           5.8, 6.6, 4.5, 6.3, 5.8, 6.1, 5.1, 5.3, 5.5, 5. , 5.1, 5.3, 5.5,
           6.7, 6.9, 5. , 5.7, 4.9, 6.7, 4.9, 5.7, 6. , 4.8, 4.9, 5.6, 5.8,
           6.1, 6.4, 5.6, 5.1, 5.6, 6.1, 5.6, 5.5, 4.8, 5.4, 5.6, 5.1, 5.1,
           5.9, 5.7, 5.2, 5. , 5.2, 5.4, 5.1])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    1.2 如何分离特征数据和标签数据

    思考:现在我们已经加入了数据集,为了训练模型,我们需要将特征数据(即输入)和标签数据(即结果)分离,使用特征输入训练后获得训练的标签结果,然后再与标签数据(实际结果)比对。该如何分离呢?

    # 使用切片提取前4列数据作为特征数据
    X_data = data[:, :4]  # 或者 X_data = data[:, :-1]
    
    # 使用切片提取最后1列数据作为标签数据
    y_data = data[:, -1]
    
    data.shape, X_data.shape, y_data.shape
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    ((150, 5), (150, 4), (150,))
    
    • 1
    # 查看未分割的数据集的前5个样本
    data[:5]
    
    • 1
    • 2
    array([[5.1, 3.5, 1.4, 0.2, 0. ],
           [4.9, 3. , 1.4, 0.2, 0. ],
           [4.7, 3.2, 1.3, 0.2, 0. ],
           [4.6, 3.1, 1.5, 0.2, 0. ],
           [5. , 3.6, 1.4, 0.2, 0. ]])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    # 查看特征数据前5个样本
    X_data[:5]
    
    • 1
    • 2
    array([[5.1, 3.5, 1.4, 0.2],
           [4.9, 3. , 1.4, 0.2],
           [4.7, 3.2, 1.3, 0.2],
           [4.6, 3.1, 1.5, 0.2],
           [5. , 3.6, 1.4, 0.2]])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    # 查看标签数据前5个样本
    y_data[:5]
    
    • 1
    • 2
    array([0., 0., 0., 0., 0.])
    
    • 1

    从结果可以看到,我们已经特征数据和标签数据已经分割开了。

    1.3 如何小尺寸的动态加载样本,而不是一下子加载全部数据集呢?

    思考:遇到数据集非常大,数据样本数非常多,需要分批次加载数据,每次批次的样本数为32,那么如何提取呢?

    动态加载批尺寸数据,使用了生成器的内容,如果不太了解,可以阅读博主之前写的文章:如何优雅地加载海量数据

    # 首先验证一下提取前32个样本,
    X_data[:32,:]
    
    • 1
    • 2
    array([[5.1, 3.5, 1.4, 0.2],
           [4.9, 3. , 1.4, 0.2],
           [4.7, 3.2, 1.3, 0.2],
           [4.6, 3.1, 1.5, 0.2],
           [5. , 3.6, 1.4, 0.2],
           [5.4, 3.9, 1.7, 0.4],
           [4.6, 3.4, 1.4, 0.3],
           [5. , 3.4, 1.5, 0.2],
           [4.4, 2.9, 1.4, 0.2],
           [4.9, 3.1, 1.5, 0.1],
           [5.4, 3.7, 1.5, 0.2],
           [4.8, 3.4, 1.6, 0.2],
           [4.8, 3. , 1.4, 0.1],
           [4.3, 3. , 1.1, 0.1],
           [5.8, 4. , 1.2, 0.2],
           [5.7, 4.4, 1.5, 0.4],
           [5.4, 3.9, 1.3, 0.4],
           [5.1, 3.5, 1.4, 0.3],
           [5.7, 3.8, 1.7, 0.3],
           [5.1, 3.8, 1.5, 0.3],
           [5.4, 3.4, 1.7, 0.2],
           [5.1, 3.7, 1.5, 0.4],
           [4.6, 3.6, 1. , 0.2],
           [5.1, 3.3, 1.7, 0.5],
           [4.8, 3.4, 1.9, 0.2],
           [5. , 3. , 1.6, 0.2],
           [5. , 3.4, 1.6, 0.4],
           [5.2, 3.5, 1.5, 0.2],
           [5.2, 3.4, 1.4, 0.2],
           [4.7, 3.2, 1.6, 0.2],
           [4.8, 3.1, 1.6, 0.2],
           [5.4, 3.4, 1.5, 0.4]])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    # 增加一个自增的索引即可滑动提取32个样本:X_data[32*i:32*(i+1),:]
    
    # 定义一个生成器,动态提取批尺寸样本
    def get_data(X_data):
        # len(X_data)//32,最后不够32个一组的样本丢弃
        for i in range(len(X_data)//32):
            yield X_data[32*i:32*(i+1),:]
    
    f_batch_data = get_data(X_data=X_data)
    print(next(f_batch_data))
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    [[5.1 3.5 1.4 0.2]
     [4.9 3.  1.4 0.2]
     [4.7 3.2 1.3 0.2]
     [4.6 3.1 1.5 0.2]
     [5.  3.6 1.4 0.2]
     [5.4 3.9 1.7 0.4]
     [4.6 3.4 1.4 0.3]
     [5.  3.4 1.5 0.2]
     [4.4 2.9 1.4 0.2]
     [4.9 3.1 1.5 0.1]
     [5.4 3.7 1.5 0.2]
     [4.8 3.4 1.6 0.2]
     [4.8 3.  1.4 0.1]
     [4.3 3.  1.1 0.1]
     [5.8 4.  1.2 0.2]
     [5.7 4.4 1.5 0.4]
     [5.4 3.9 1.3 0.4]
     [5.1 3.5 1.4 0.3]
     [5.7 3.8 1.7 0.3]
     [5.1 3.8 1.5 0.3]
     [5.4 3.4 1.7 0.2]
     [5.1 3.7 1.5 0.4]
     [4.6 3.6 1.  0.2]
     [5.1 3.3 1.7 0.5]
     [4.8 3.4 1.9 0.2]
     [5.  3.  1.6 0.2]
     [5.  3.4 1.6 0.4]
     [5.2 3.5 1.5 0.2]
     [5.2 3.4 1.4 0.2]
     [4.7 3.2 1.6 0.2]
     [4.8 3.1 1.6 0.2]
     [5.4 3.4 1.5 0.4]]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    2. 高级索引

    numpy的ndarray对象支持数组索引、布尔索引和花式索引。

    2.1 数组索引

    例如下面这个代码,[0,4,7],[0, 1, 2]提取的数据样本实际是(0,0),(4,1),(7,2),其实就是对位取数

    X_data[[0,4,7],[0, 1, 2]]
    
    • 1
    array([5.1, 3.6, 1.5])
    
    • 1
    X_data[:7,:]
    
    • 1
    array([[5.1, 3.5, 1.4, 0.2],
           [4.9, 3. , 1.4, 0.2],
           [4.7, 3.2, 1.3, 0.2],
           [4.6, 3.1, 1.5, 0.2],
           [5. , 3.6, 1.4, 0.2],
           [5.4, 3.9, 1.7, 0.4],
           [4.6, 3.4, 1.4, 0.3]])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    可以和X_data原始特征数据比对一下,发现与描述一致。

    2.2 布尔索引

    布尔索引在机器学习和深度学习时被大量使用,在过滤数据时非常有用。
    其格式为X[条件表达式]

    思考:现在我需要分析花萼宽度>4.5的样本在整个样本中的比例是多少,该如何处理呢?

    # 索引的第一个值为样本行数,选择所有,第二个值为指定的第一列
    
    X_data_column0 = X_data[X_data[:,0]>4.5]
    percent = len(X_data_column0)/len(X_data)
    percent
    
    • 1
    • 2
    • 3
    • 4
    • 5
    0.9666666666666667
    
    • 1

    可以看到花萼宽度>4.5的样本占比非常高。

    2.3 花式索引

    将来再研究。

    写在末尾:

    • 博客简介:专注AIoT领域,追逐未来时代的脉搏,记录路途中的技术成长!
    • 专栏简介:从0到1掌握数据科学常用库Numpy、Matploblib、Pandas。
    • 面向人群:AI初级学习者
    • 专栏计划:接下来会逐步发布跨入人工智能的系列博文,敬请期待

  • 相关阅读:
    接口隔离原则(Interface Segregation Principle)
    springcloud16:总结配置中心+消息中心总结篇
    【Linux】进程状态详解
    2023年CSP-S赛后总结(2023CSP-S题解+游记)
    网络安全--使用Kali进行ARP欺骗(详细教程)
    含文档+PPT+源码等]精品基于SSM的校园二手交易平台[包运行成功]程序设计源码计算机毕设
    【Promise】黑马vue视频笔记(十一)
    Citespace、vosviewer、R语言的文献计量学可视化分析技术及全流程文献可视化SCI论文高效写作方法
    基于spring boot开发的6个秋招必备项目,搞起来
    在eclipse中安装properties插件PropertiesEditor及设置(附图),ASCII码转换成中文
  • 原文地址:https://blog.csdn.net/RobotFutures/article/details/126176343