如何在Python中将索引、切片和重塑用于机器学习的NumPy数组

机器学习数据表示为数组。

在Python中,数据几乎普遍表示为NumPy数组。

如果你是Python的新手,你可能会对一些Python式的数据访问方式感到困惑,例如负索引和数组切片。

在本教程中,你将了解如何在NumPy数组中正确操作和访问数据。

完成本教程后,你将了解:

  • 如何将列表数据转换为NumPy数组。
  • 如何使用Pythonic索引和切片访问数据。
  • 如何调整数据大小以满足某些机器学习API的期望。

我们开始吧。

教程概述

本教程分为4个部分,它们是:

  • 从列表到数组。
  • 数组索引。
  • 数组切片。
  • 阵列整形。

1.从列表到数组

通常,我建议使用Pandas甚至NumPy函数从文件加载数据。

有关示例,请参阅帖子:

本节假设你已经通过其他方式加载或生成了数据,现在使用Python列表表示数据。

让我们看看如何将列表中的数据转换为NumPy数组。

一维列表到数组

你可以加载数据或生成数据并将其作为列表进行访问。

可以通过调用NumPy函数array()将一维数据列表转换为数组。

# one dimensional example
from numpy import array
# list of data
data = [11, 22, 33, 44, 55]
# array of data
data = array(data)
print(data)
print(type(data))

运行该示例会将一维列表转换为NumPy数组。

[11 22 33 44 55]
<class 'numpy.ndarray'>

二维列表到数组

在机器学习中,你更有可能拥有二维数据。

这是一个数据表,其中每行代表一个新观测,每列代表一个新特征。

也许你使用自定义代码生成了数据或加载了数据,现在你就有了一个二维列表。每个二维代表一个新的观察结果。

你可以通过调用array()函数,以与上面相同的方式将列表列表转换为NumPy数组。

# two dimensional example
from numpy import array
# list of data
data = [[11, 22],
		[33, 44],
		[55, 66]]
# array of data
data = array(data)
print(data)
print(type(data))

运行该示例将显示成功转换的数据。

[[11 22]
 [33 44]
 [55 66]]
<class 'numpy.ndarray'>

2.数组索引

一旦使用NumPy数组表示数据,就可以使用索引访问它。

让我们看一些通过索引访问数据的示例。

一维索引

通常,索引的工作方式与你在使用其他编程语言(如Java、C#和C++)时所期望的一样。

例如,你可以使用方括号运算符[]来访问元素,该运算符指定要检索的值的零偏移索引。

# simple indexing
from numpy import array
# define array
data = array([11, 22, 33, 44, 55])
# index data
print(data[0])
print(data[4])

运行该示例将打印数组中的第一个和最后一个值。

11
55

为数组的界限指定太大的整数将导致错误。

# simple indexing
from numpy import array
# define array
data = array([11, 22, 33, 44, 55])
# index data
print(data[5])

运行该示例将打印以下错误:

IndexError: index 5 is out of bounds for axis 0 with size 5

一个关键区别是你可以使用负索引来检索从数组末尾偏移的值。

例如,索引-1表示数组中的最后一项。索引-2返回当前示例中第一个项目的倒数第二个项目,一直返回到-5。

# simple indexing
from numpy import array
# define array
data = array([11, 22, 33, 44, 55])
# index data
print(data[-1])
print(data[-5])

运行该示例将打印数组中的最后一项和第一项。

55
11

二维索引

索引二维数据类似于索引一维数据,不同之处在于使用逗号分隔每个维度的索引。

data[0,0]

这与基于C的语言不同,在C语言中,每个维度都使用单独的方括号运算符。

data[0][0]

例如,我们可以按如下方式访问第一行和第一列:

# 2d indexing
from numpy import array
# define array
data = array([[11, 22], [33, 44], [55, 66]])
# index data
print(data[0,0])

运行该示例将打印数据集中的第一项。

11

如果我们对第一行中的所有项目感兴趣,则可以将第二维索引留空,例如:

# 2d indexing
from numpy import array
# define array
data = array([[11, 22], [33, 44], [55, 66]])
# index data
print(data[0,])

这将打印第一行数据。

[11 22]

3.数组切片

到目前为止,一切顺利;创建和索引数组看起来很熟悉。

现在我们来看数组切片,这是一个会给Python和NumPy数组初学者带来问题的特性。

像列表和NumPy数组这样的结构可以切片。这意味着可以对结构的子序列进行索引和检索。

当指定输入变量和输出变量,或将训练行与测试行分开时,这在机器学习中最有用。

切片是使用冒号运算符“:”指定的,在列前后分别带有“from”和“to”索引。切片从“from”索引延伸,并在“to”索引之前结束一项。

data[from:to]

让我们来做一些例子。

一维切片

你可以通过指定不带索引的切片‘:’来访问数组维度中的所有数据。

# simple slicing
from numpy import array
# define array
data = array([11, 22, 33, 44, 55])
print(data[:])

运行该示例将打印数组中的所有元素。

[11 22 33 44 55]

通过指定从索引0开始到索引1结束的切片,可以对数组的第一项进行切片(在“to”索引之前的一项)。

# simple slicing
from numpy import array
# define array
data = array([11, 22, 33, 44, 55])
print(data[0:1])

运行该示例将返回具有第一个元素的子数组。

[11]

我们也可以在切片中使用负索引。例如,我们可以通过从-2(倒数第二个项目)开始切片,并且不指定“to”索引来对列表中的最后两个项目进行切片;这会将切片带到维度的末尾。

# simple slicing
from numpy import array
# define array
data = array([11, 22, 33, 44, 55])
print(data[-2:])

运行该示例将返回仅包含最后两项的子数组。

[44 55]

二维切片

让我们看看机器学习中最可能使用的两个二维切片示例。

拆分输入和输出要素

将加载的数据拆分为输入变量(X)和输出变量(Y)是很常见的。

我们可以通过将最后一列之前的所有行和所有列切片,然后分别索引最后一列来实现这一点。

对于输入特性,我们可以通过在行索引中指定‘:’并在列索引中指定:-1来选择除最后一行之外的所有行和所有列。

X = [:, :-1]

对于输出列,我们可以使用‘:’再次选择所有行,并通过指定-1(索引)来仅索引最后一列。

y = [:, -1]

将所有这些放在一起,我们可以将3列二维数据集分为输入和输出数据,如下所示:

# split input and output
from numpy import array
# define array
data = array([[11, 22, 33],
		[44, 55, 66],
		[77, 88, 99]])
# separate data
X, y = data[:, :-1], data[:, -1]
print(X)
print(y)

运行该示例将打印分隔的x和y元素。请注意,X是二维数组,而Y是一维数组。

[[11 22]
 [44 55]
 [77 88]]
[33 66 99]

拆分训练行和测试行

将加载的数据集分割成单独的训练集和测试集是很常见的。

这是行的拆分,其中某些部分将用于训练模型,其余部分将用于估计已训练模型的技能。

这将涉及通过在第二个维度索引中指定‘:’来对所有列进行切片。训练数据集将是从开始到拆分点的所有行。

dataset
train = data[:split, :]

测试数据集将是从拆分点到维度末尾的所有行。

test = data[split:, :]

将所有这些放在一起,我们可以在人为的拆分点2处拆分数据集。

# split train and test
from numpy import array
# define array
data = array([[11, 22, 33],
		[44, 55, 66],
		[77, 88, 99]])
# separate data
split = 2
train,test = data[:split,:],data[split:,:]
print(train)
print(test)

运行该示例将选择前两行用于训练,最后一行用于测试集。

[[11 22 33]
[44 55 66]]
[[77 88 99]]

4.数组重塑

对数据进行切片后,你可能需要对其进行重塑。

例如,一些库(如scikit-learn)可能需要输出变量(y)中的一维数组被重塑为二维数组,该二维数组由一列及每列对应的结果组成。

一些算法,如Kera中的长短期记忆递归神经网络,需要将输入指定为由样本、时间步长和特征组成的三维数组。

了解如何重塑NumPy数组是非常重要的,这样你的数据就能满足于特定Python库。我们来看看下面这两个例子。

数据形状

NumPy数组具有一个形状属性,该属性返回数组每个维度的长度的元组。

例如:

# array shape
from numpy import array
# define array
data = array([11, 22, 33, 44, 55])
print(data.shape)

运行该示例将打印一个维度的元组。

(5,)

对于二维数组,返回两个长度的元组。

# array shape
from numpy import array
# list of data
data = [[11, 22],
		[33, 44],
		[55, 66]]
# array of data
data = array(data)
print(data.shape)

运行此示例将返回一个包含行数和列数的元组。

(3, 2)

你可以在形状维度中使用数组维度的大小,例如指定参数。

可以像访问数组一样访问元组的元素,第0个索引表示行数,第1个索引表示列数。例如:

# array shape
from numpy import array
# list of data
data = [[11, 22],
		[33, 44],
		[55, 66]]
# array of data
data = array(data)
print('Rows: %d' % data.shape[0])
print('Cols: %d' % data.shape[1])

运行该示例将访问每个维度的特定大小。

Rows: 3
Cols: 2

将一维阵列重塑为二维阵列

通常需要将一维数组重塑为具有一列和多个数组的二维数组。

NumPy在NumPy数组对象上提供了可用于重塑数据的reshape()函数。

函数的作用是:接受指定数组新形状的单个参数。在将一维数组重塑为具有一列的二维数组的情况下,元组将是作为第一维(data.shape[0])的数组的形状,并且对于第二维是1。

data = data.reshape((data.shape[0], 1))

把所有这些放在一起,我们会得到下面的工作示例。

# reshape 1D array
from numpy import array
from numpy import reshape
# define array
data = array([11, 22, 33, 44, 55])
print(data.shape)
# reshape
data = data.reshape((data.shape[0], 1))
print(data.shape)

运行该示例将打印一维数组的形状,将数组重塑为5行1列,然后打印此新形状。

(5,)
(5, 1)

将二维数组重塑为三维数组

对于期望一个或多个时间步长和一个或多个特征的多个样本的算法,通常需要将其中每行代表一个序列的二维数据重塑为三维数组。

Kera深度学习库中的LSTM递归神经网络模型就是一个很好的例子。

可以直接使用重塑函数,指定新维度。这一点在每个序列具有多个时间步长的示例中很清楚,每个时间步长具有一个观测(特征)。

我们可以使用数组的形状属性中的大小来指定样本(行数)和列数(时间点),并将特征数固定为1。

data.reshape((data.shape[0], data.shape[1], 1))

把所有这些放在一起,我们会得到下面的工作示例。

# reshape 2D array
from numpy import array
# list of data
data = [[11, 22],
		[33, 44],
		[55, 66]]
# array of data
data = array(data)
print(data.shape)
# reshape
data = data.reshape((data.shape[0], data.shape[1], 1))
print(data.shape)

运行该示例首先打印二维数组中每个维度的大小,重塑数组的形状,然后汇总新三维数组的形状。

(3, 2)
(3, 2, 1)

进一步阅读

如果你想深入了解,本节提供了更多有关该主题的资源。

00

Python

发表评论

邮箱地址不会被公开。 必填项已用*标注

什么阻碍了你实现迈入机器学习领域的目标?

什么阻碍了你实现迈入机器学习领域的目标?

2020-04-22 机器学习

如果你在为进入机器学习领域而挣扎,感觉到有什么东西阻止了自己的开始,那么你应该看看这篇文章。 在这篇文章中,我们会讨论阻止进入机器学习领域的自我限制的信念,让你明白面临的问题。 几乎总是一种自我限制的信念阻碍了你们的进步。 也许你会在一个或多个这样的信念中看到自己。如果是这样的话, [......]

了解详情

R语言机器学习迷你课程

R语言机器学习迷你课程

2020-08-12 机器学习

在这个迷你课程中,你将发现如何开始,构建精确的模型,并自信地完成在14天内使用R预测建模机器学习项目。 这是一个重要而重要的文章。你可能想把它书签。 了解如何准备数据,拟合机器学习模型,并用我的新书评估他们在r上的预测,包括14步教程、3个项目和完整源代码。 我们开始吧。 [......]

了解详情

关于机器学习的几点思考

关于机器学习的几点思考

2020-04-26 机器学习

机器学习是一个大的、跨学科的研究领域。 你可以通过机器学习获得令人印象深刻的结果,并找到非常具有挑战性的问题的解决方案。但这只是更广泛的机器学习领域的一小部分,通常被称为预测建模或预测分析。 在这篇文章中,你将发现如何改变你对机器学习的思考方式,以便更好地为你提供机器学习实践者的服务。 [......]

了解详情

找到你的机器学习部落

找到你的机器学习部落

2020-04-26 机器学习

机器学习是一个充满算法和数据的迷人而强大的研究领域。 问题是,有这么多不同类型的人对机器学习感兴趣,每个人都有不同的需求。重要的是要了解你想要从机器学习中得到什么,并根据这些需求调整你的自学。 如果你不这样做,你很容易就会陷入困境,迷失方向,失去兴趣,得不到你想要的东西。 找到 [......]

了解详情

应用机器学习过程

应用机器学习过程

2020-04-26 机器学习

随着时间的推移,在处理应用机器学习问题时,你会开发出一种模式或流程,以快速获得良好的正常结果。 一旦开发完成,你就可以在一个又一个项目上反复使用此过程。你的流程越健壮、越发达,你就能越快地获得可靠的结果。 在这篇文章中,我想与你分享我解决机器学习问题的过程框架。 你可以将其用作下一 [......]

了解详情