前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在Python机器学习中如何索引、切片和重塑NumPy数组

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

作者头像
用户9527
发布2018-02-02 17:03:48
19.1K0
发布2018-02-02 17:03:48

机器学习中的数据被表示为数组。

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

如果你是Python的新手,在访问数据时你可能会被一些python专有的方式困惑,例如负向索引和数组切片。

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

完成本教程后,你将知道:

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

让我们开始吧。

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

照片由BjörnSöderqvist,保留一些权利。

教程概述

本教程分为4个部分; 他们是:

  1. 从列表到数组
  2. 数组索引
  3. 数组切片
  4. 数组重塑

1.从列表到数组

一般来说,我建议使用Pandas或NumPy函数从文件加载数据。

有关示例,请参阅帖子:

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

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

一维列表到数组

你可以加载或生成你的数据,并将它看作一个列表来访问。

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

代码语言:txt
复制
# 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数组。

代码语言:txt
复制
[11 22 33 44 55]
<class 'numpy.ndarray'>

二维列表到数组

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

这是一个数据表,其中每一行代表一个新的发现,每一列代表一个新的特征。

也许你通过使用自定义代码生成或加载数据,现在你有了二维列表。每个列表表示一个新发现。

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

代码语言:txt
复制
# 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))

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

代码语言:txt
复制
[[11 22]
[33 44]
[55 66]]
<class 'numpy.ndarray'>

2.数组索引

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

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

一维索引

一般来说,索引的工作方式与你使用其他编程语言(如Java、C#和C ++)的经验相同。

例如,你可以使用括号操作符[]来访问元素,指定零偏移索引来检索值。

代码语言:txt
复制
# simple indexing
from numpy import array
# define array
data = array([11, 22, 33, 44, 55])
# index data
print(data[0])
print(data[4])

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

代码语言:txt
复制
11
55

指定大于边界的值将导致错误。

代码语言:txt
复制
# simple indexing
from numpy import array
# define array
data = array([11, 22, 33, 44, 55])
# index data
print(data[5])

运行该示例将输出以下错误:

代码语言:txt
复制
IndexError: index 5 is out of bounds for axis 0 with size 5

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

例如,索引-1代表数组中的最后一项。索引-2代表倒数第二项,-5代表当前示例的第一项。

代码语言:txt
复制
# simple indexing
from numpy import array
# define array
data = array([11, 22, 33, 44, 55])
# index data
print(data[-1])
print(data[-5])

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

代码语言:txt
复制
55
11

二维索引

索引二维数据与索引一维数据类似,区别在于用逗号分隔每个维度的索引。

代码语言:txt
复制
data[0,0]

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

代码语言:txt
复制
data[0][0]

例如,我们可以访问第一行和第一列,如下所示:

代码语言:txt
复制
# 2d indexing
from numpy import array
# define array
data = array([[11, 22], [33, 44], [55, 66]])
# index data
print(data[0,0])

运行该示例将输出数据集中的第一项。

代码语言:txt
复制
11

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

代码语言:txt
复制
# 2d indexing
from numpy import array
# define array
data = array([[11, 22], [33, 44], [55, 66]])
# index data
print(data[0,])

这将输出第一行数据。

代码语言:txt
复制
[11 22]

3.数组切片

到目前为止还挺好; 创建和索引数组看起来都还很熟悉。

现在我们来进行数组切片,对于Python和NumPy数组的初学者来说,这里可能会引起某些问题。

像列表和NumPy数组的结构可以被切片。这意味着该结构的一个子序列也可以被索引和检索。

在机器学习中指定输入输出变量,或从测试行分割训练行时切片是最有用的。

在冒号运算符':'的前后分别用'from '和'to '来指定切片。切片的内容是从'from'的索引到'to'索引的前一项。

代码语言:txt
复制
data[from:to]

让我们通过一些示例来了解一下。

一维切片

你可以通过':'前后不指定任何索引来访问数组维度中的所有数据。

代码语言:txt
复制
# simple slicing
from numpy import array
# define array
data = array([11, 22, 33, 44, 55])
print(data[:])

运行该示例输出数组中的所有元素。

代码语言:txt
复制
[11 22 33 44 55]

可以通过指定从索引0开始到索引1结束('to'索引的前一项)切片出数组的第一项。

代码语言:txt
复制
# simple slicing
from numpy import array
# define array
data = array([11, 22, 33, 44, 55])
print(data[0:1])

运行该示例返回一个包含第一个元素的子数组。

代码语言:txt
复制
[11]

我们也可以在切片中使用负向索引。例如,我们可以通过在-2(倒数第二项)处开始切片并且不指定'to'索引来切割列表中的最后两项;这就会一直切到维度末端。

代码语言:txt
复制
# simple slicing
from numpy import array
# define array
data = array([11, 22, 33, 44, 55])
print(data[-2:])

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

代码语言:txt
复制
[44 55]

二维切片

我们来看看你最有可能在机器学习中使用的二维切片的两个例子。

拆分输入和输出功能

通常将加载的数据分解为输入变量(X)和输出变量(y)。

我们可以这样做,将最后一列前的所有行和列分段,然后单独索引最后一列。

对于输入要素,在行索引中我们可以通过指定':'来选择最后一行外的所有行和列,并且在列索引中指定-1。

代码语言:txt
复制
X = [:, :-1]

对于输出列,我们可以再次使用':'选择所有行,并指定-1索引来检索最后一列

代码语言:txt
复制
y = [:, -1]

综上,我们可以把一个3列的二维数据集分成如下的输入和输出数据:

代码语言:txt
复制
# 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是一维数组。

代码语言:txt
复制
[[11 22]
[44 55]
[77 88]]
[33 66 99]
拆分训练行和测试行

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

分割一整行,其中一部分用于训练模型,剩下的部分用于评估训练模型的能力。

这包括在第二维索引中指定':'来切分所有的列。从开始到分割点的所有行构成训练数据集。

代码语言:txt
复制
dataset
train = data[:split, :]

从分割点到末尾的所有行则构成测试数据集。

代码语言:txt
复制
test = data[split:, :]

综上所述,我们可以在人为的分割点处二分数据集。

代码语言:txt
复制
# 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)

运行该示例,前两行为训练集,最后一行为测试集。

代码语言:txt
复制
[[11 22 33]
[44 55 66]]
[[77 88 99]]

4.数组重塑

切片数据后,你可能需要重塑数据。

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

有些算法,如Keras中的时间递归神经网络(LSTM),需要输入特定的包含样本、时间步骤和特征的三维数组。

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

数据形状

NumPy数组有一个shape属性,它返回一个元组,元组中的每个元素表示相应的数组每一维的长度。

例如:

代码语言:txt
复制
# array shape
from numpy import array
# define array
data = array([11, 22, 33, 44, 55])
print(data.shape)

运行该示例输出一个表示一维数组的元组。

代码语言:txt
复制
(5,)

二维数组则返回具有两个长度的元组。

代码语言:txt
复制
# 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)

运行该示例,返回具有行数和列数的元组。

代码语言:txt
复制
(3, 2)

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

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

代码语言:txt
复制
# 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])

运行该示例,显示每一维的具体数值。

代码语言:txt
复制
Rows: 3
Cols: 2

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

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

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

reshape()函数接受一个参数,该参数指定数组的新形状。将一维数组重塑为具有一列的二维数组,在这种情况下,该元组将作为第一维(data.shape[0])中的数组形状和第二维的中1。

代码语言:txt
复制
data = data.reshape((data.shape[0], 1))

综上所述,我们得到如下示例。

代码语言:txt
复制
# 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列的新形状,并输出。

代码语言:txt
复制
(5,)
(5, 1)

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

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

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

重塑函数可以直接使用,指定出新的维度。每一列有多个时间步,每个时间步都有一个观察点(特征),这说的很明白。

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

代码语言:txt
复制
data.reshape((data.shape[0], data.shape[1], 1))

综上所述,我们得到如下示例。

代码语言:txt
复制
# 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)

运行该示例,先输出二维数组中每一维的大小,再重塑数组,然后得出新的三维数组的形状。

代码语言:txt
复制
(3, 2)
(3, 2, 1)

概要

在本教程中,你了解了如何使用Python访问和重塑NumPy数组中的数据。

具体来说,你了解到:

  • 如何将你的列表数据转换为NumPy数组。
  • 如何使用Pythonic索引和切片访问数据。
  • 如何调整数据大小以满足某些机器学习API的需求。
评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 教程概述
  • 1.从列表到数组
    • 一维列表到数组
      • 二维列表到数组
      • 2.数组索引
        • 一维索引
          • 二维索引
          • 3.数组切片
            • 一维切片
              • 二维切片
                • 拆分输入和输出功能
                • 拆分训练行和测试行
            • 4.数组重塑
              • 数据形状
                • 将一维数组重塑为二维数组
                  • 将二维数组重塑为三维数组
                  • 概要
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档