这是机器未来的第41篇文章
原文首发地址:https://blog.csdn.net/RobotFutures/article/details/126176343
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(','))
title:sepal_length,sepal_width,petal_length,petal_width,target_names
# 从上面代码的执行结果可以看到,数据集有5个标题,对应5列数据
# 前4列为鸢尾花的特征,最后1列为鸢尾花的分类
# sepal_length - 花萼长度
# sepal_width - 花萼宽度
# petal_length - 花瓣长度
# petal_width - 花萼宽度
# target_names - 目标名称
# 取2行数据,看一下数据值与类型
data[:2]
[['5.1', '3.5', '1.4', '0.2', '0'], ['4.9', '3.0', '1.4', '0.2', '0']]
# 从上面列表提取的前2行数据可以看到,它的数据类型为字符串,在将data从list转换为ndarray数组时,直接做数据类型转换,转换为float
data = np.array(data, dtype=float)
# 和列表一样,ndarray对象也可以使用切片的方式访问数组
# 这里提取前4行数据查看一下数据值的范围及数据类型
data[:4]
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. ]])
思考:在做数据预处理时可能会分析特征数据与标签数据的相关性,我们需要提取指定列的数据与标签数据做分析,那么如何提取某一列数据呢?
使用切片来提取。先看一下数据的shape
data.shape
(150, 5)
可以看到是150行,5列,现在需要提取第3列数据,可以这样操作
# 逗号前的:表示提取全部行,逗号后的2表示提取第3列
data[:,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])
思考:现在我们已经加入了数据集,为了训练模型,我们需要将特征数据(即输入)和标签数据(即结果)分离,使用特征输入训练后获得训练的标签结果,然后再与标签数据(实际结果)比对。该如何分离呢?
# 使用切片提取前4列数据作为特征数据
X_data = data[:, :4] # 或者 X_data = data[:, :-1]
# 使用切片提取最后1列数据作为标签数据
y_data = data[:, -1]
data.shape, X_data.shape, y_data.shape
((150, 5), (150, 4), (150,))
# 查看未分割的数据集的前5个样本
data[:5]
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. ]])
# 查看特征数据前5个样本
X_data[:5]
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个样本
y_data[:5]
array([0., 0., 0., 0., 0.])
从结果可以看到,我们已经特征数据和标签数据已经分割开了。
思考:遇到数据集非常大,数据样本数非常多,需要分批次加载数据,每次批次的样本数为32,那么如何提取呢?
动态加载批尺寸数据,使用了生成器的内容,如果不太了解,可以阅读博主之前写的文章:如何优雅地加载海量数据
# 首先验证一下提取前32个样本,
X_data[:32,:]
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]])
# 增加一个自增的索引即可滑动提取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))
[[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]]
numpy的ndarray对象支持数组索引、布尔索引和花式索引。
例如下面这个代码,[0,4,7],[0, 1, 2]提取的数据样本实际是(0,0),(4,1),(7,2),其实就是对位取数
X_data[[0,4,7],[0, 1, 2]]
array([5.1, 3.6, 1.5])
X_data[:7,:]
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]])
可以和X_data原始特征数据比对一下,发现与描述一致。
布尔索引在机器学习和深度学习时被大量使用,在过滤数据时非常有用。
其格式为X[条件表达式]
思考:现在我需要分析花萼宽度>4.5的样本在整个样本中的比例是多少,该如何处理呢?
# 索引的第一个值为样本行数,选择所有,第二个值为指定的第一列
X_data_column0 = X_data[X_data[:,0]>4.5]
percent = len(X_data_column0)/len(X_data)
percent
0.9666666666666667
可以看到花萼宽度>4.5的样本占比非常高。
将来再研究。
写在末尾:
- 博客简介:专注AIoT领域,追逐未来时代的脉搏,记录路途中的技术成长!
- 专栏简介:从0到1掌握数据科学常用库Numpy、Matploblib、Pandas。
- 面向人群:AI初级学习者
- 专栏计划:接下来会逐步发布跨入人工智能的系列博文,敬请期待
- Python零基础快速入门系列
- 数据科学系列
- 人工智能开发环境搭建系列
- 机器学习系列
- 物体检测快速入门系列
- 自动驾驶物体检测系列
- …