9.4 NumPy 数组的基础

本节是《Python 数据科学手册》(Python Data Science Handbook)的摘录。

译者:飞龙

协议:CC BY-NC-SA 4.0

Python 中的数据操作几乎与 NumPy 数组操作同义:即使是像 Pandas 这样的新工具也是围绕 NumPy 数组构建的。本节将介绍几个示例,使用 NumPy 数组操作来访问数据和子数组,以及拆分,重塑和连接数组。

虽然这里显示的操作类型可能看起来有点枯燥和怪异,但它们构成了本书中使用的许多其他示例的积木。尽快了解它们!

我们将在这里介绍几类基本数组操作:

  • 数组的属性:确定数组的大小,形状,内存消耗和数据类型
  • 数组的索引:获取和设置各个数组元素的值
  • 数组切片:在较大的数组中获取和设置较小的子数组
  • 数组的重塑:更改给定数组的形状
  • 数组的连接和分割:将多个数组合并为一个数组,并将一个数组拆分为多个数组

NumPy 数组属性

首先让我们讨论一些有用的数组属性。

我们首先定义三个随机数组,一维,二维和三维数组。我们将使用 NumPy 的随机数生成器,并使用设定值设置种子,来确保每次运行此代码时,生成相同的随机数组:

import numpy as np
np.random.seed(0)  # 用于可复现的种子x1 = np.random.randint(10, size=6)  # 一维数组
x2 = np.random.randint(10, size=(3, 4))  # 二维数组
x3 = np.random.randint(10, size=(3, 4, 5))  # 三维数组

每个数组都有属性ndim(维数),shape(每个维度的大小)和size(数组的总大小):

print("x3 ndim: ", x3.ndim)
print("x3 shape:", x3.shape)
print("x3 size: ", x3.size)'''
x3 ndim:  3
x3 shape: (3, 4, 5)
x3 size:  60
'''

另一个有用的属性是dtype,数组的数据类型(我们之前在“了解 Python 中的数据类型”中讨论过):

print("dtype:", x3.dtype)# dtype: int64

其他属性包括itemsize,它列出每个数组元素的大小(以字节为单位)和nbytes,它列出了数组的总大小(以字节为单位):

print("itemsize:", x3.itemsize, "bytes")
print("nbytes:", x3.nbytes, "bytes")'''
itemsize: 8 bytes
nbytes: 480 bytes
'''

一般来说,我们希望nbytes等于itemsize乘以size

数组索引:访问单个元素

如果你熟悉 Python 的标准列表索引,NumPy 中的索引将会非常眼熟。

在一维数组中,可以通过在方括号中指定所需的索引(从零开始计算),来访问第i值,就像使用 Python 列表一样:

x1# array([5, 0, 3, 3, 7, 9])x1[0]# 5x1[4]# 7

要从数组的末尾开始索引,可以使用负索引:

x1[-1]# 9x1[-2]# 7

在多维数组中,可以使用以逗号分隔的索引元组来访问项目:

x2'''
array([[3, 5, 2, 4],[7, 6, 8, 8],[1, 6, 7, 7]])
'''x2[0, 0]# 3x2[2, 0]# 1x2[2, -1]# 7

也可以使用以上任何索引表示法修改值:

x2[0, 0] = 12
x2'''
array([[12,  5,  2,  4],[ 7,  6,  8,  8],[ 1,  6,  7,  7]])
'''

请记住,与 Python 列表不同,NumPy 数组具有固定类型。

这意味着,例如,如果你尝试将浮点值插入整数数组,则该值将被静默截断。 不要意识不到这种行为!

x1[0] = 3.14159  # 会截断!
x1# array([3, 0, 3, 3, 7, 9])

数组切片:访问子数组

就像我们可以使用方括号来访问单个数组元素一样,我们也可以使用它们以及由冒号(:)标记的切片表示法,来访问子数组。

NumPy 切片语法遵循标准 Python 列表的语法;要访问数组x的切片,请使用:

x[start:stop:step]

如果其中任何一个未指定,它们默认为start = 0stop = 维度大小step = 1

我们看一下如何在一维和多维中访问子数组。

一维子数组

x = np.arange(10)
x# array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])x[:5]  # 前五个元素# array([0, 1, 2, 3, 4])x[5:]  # 下标 5 后面的元素# array([5, 6, 7, 8, 9])x[4:7]  # 中间的子数组# array([4, 5, 6])x[::2]  # 每个其它元素# array([0, 2, 4, 6, 8])x[1::2]  # 每个其它元素,起始于下标 1# array([1, 3, 5, 7, 9])

一个可能令人困惑的情况是step值为负。在这种情况下,交换startstop的默认值。这成为反转数组的便捷方法:

x[::-1]  # 所有元素反过来# array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])x[5::-2]  # 反向的每个其它元素,起始于下标 5# array([5, 3, 1])

多维子数组

多维切片以相同的方式工作,多个切片用逗号分隔。例如:

x2'''
array([[12,  5,  2,  4],[ 7,  6,  8,  8],[ 1,  6,  7,  7]])
'''x2[:2, :3]  # 两行三列'''
array([[12,  5,  2],[ 7,  6,  8]])
'''x2[:3, ::2]  # 所有行,每个其它列'''
array([[12,  2],[ 7,  8],[ 1,  7]])
'''

最后,子数组的维度甚至可以一起反转:

x2[::-1, ::-1]'''
array([[ 7,  7,  6,  1],[ 8,  8,  6,  7],[ 4,  2,  5, 12]])
'''

访问数组的行和列

一个常用的例程是访问数组的单个行或列。

这可以通过组合索引和切片来完成,使用由单个冒号(:)标记的空切片:

print(x2[:, 0])  # x2 的第一列 # [12  7  1]print(x2[0, :])  # x2 的第一行# [12  5  2  4]

在访问行的情况下,可以省略空切片来获得更紧凑的语法:

print(x2[0])  # 等价于 x2[0, :]# [12  5  2  4]

作为无副本视图的子数组

数组切片的一个重要且非常有用的事情,是它们返回视图而不是数组数据的副本。这是 NumPy 数组切片与 Python 列表切片的不同之处:在列表中,切片是副本。

考虑我们之前的二维数组:

print(x2)'''
[[12  5  2  4][ 7  6  8  8][ 1  6  7  7]]
'''

让我们从中提取2x2子数组:

x2_sub = x2[:2, :2]
print(x2_sub)'''
[[12  5][ 7  6]]
'''

现在,如果我们修改这个子数组,我们会看到原始数组已经改变了!注意:

x2_sub[0, 0] = 99
print(x2_sub)'''
[[99  5][ 7  6]]
'''print(x2)'''
[[99  5  2  4][ 7  6  8  8][ 1  6  7  7]]
'''

这种默认行为实际上非常有用:这意味着当我们处理大型数据集时,我们可以访问和处理这些数据集的各个部分,而无需复制底层数据缓冲区。

创建数组的副本

尽管数组视图具有很好的特性,但有时显式复制数组或子数组中的数据也很有用。 使用copy()方法可以很容易地做到:

x2_sub_copy = x2[:2, :2].copy()
print(x2_sub_copy)'''
[[99  5][ 7  6]]
'''

如果我们现在修改此子数组,则不会触及原始数组:

x2_sub_copy[0, 0] = 42
print(x2_sub_copy)'''
[[42  5][ 7  6]]
'''print(x2)'''
[[99  5  2  4][ 7  6  8  8][ 1  6  7  7]]
'''

数组的形状调整

另一种有用的操作类型是数组的形状调整。最灵活的方法是使用reshape方法。例如,如果要将数字 1 到 9 放在3x3网格中,则可以执行以下操作:

grid = np.arange(1, 10).reshape((3, 3))
print(grid)'''
[[1 2 3][4 5 6][7 8 9]]
'''

请注意,为此,初始数组的大小必须匹配形状调整的数组的大小。在可能的情况下,reshape方法将使用初始数组的非副本视图,但对于非连续的内存缓冲区,情况并非总是如此。

另一种常见的形状调整是将一维数组转换为二维行或列矩阵。这可以使用reshape方法完成,或者通过在切片操作中使用newaxis关键字更容易地完成:

x = np.array([1, 2, 3])# 通过 reshape 来创建行向量
x.reshape((1, 3))# array([[1, 2, 3]])# 通过 newaxis 来创建行向量
x[np.newaxis, :]# array([[1, 2, 3]])# 通过 reshape 来创建列向量
x.reshape((3, 1))'''
array([[1],[2],[3]])
'''# 通过 newaxis 来创建列向量
x[:, np.newaxis]'''
array([[1],[2],[3]])
'''

我们将在本书的其余部分经常看到这种类型的转换。

数组的连接和分割

所有上述例程都适用于单个数组。也可以将多个数组合并为一个,并与之相反,将单个数组拆分为多个数组。我们将在这里看看这些操作。

数组的连接

在 NumPy 中连接两个数组,主要是使用例程np.concatenatenp.vstacknp.hstack完成的。

np.concatenate将数组元组或列表作为它的第一个参数,我们可以在这里看到:

x = np.array([1, 2, 3])
y = np.array([3, 2, 1])
np.concatenate([x, y])# array([1, 2, 3, 3, 2, 1])

你还可以同时连接两个以上的数组:

z = [99, 99, 99]
print(np.concatenate([x, y, z]))# [ 1  2  3  3  2  1 99 99 99]

它也可以用于二维数组:

grid = np.array([[1, 2, 3],[4, 5, 6]])# 沿第一个轴连接
np.concatenate([grid, grid])'''
array([[1, 2, 3],[4, 5, 6],[1, 2, 3],[4, 5, 6]])
'''# 沿第二个轴连接(下标从零开始)
np.concatenate([grid, grid], axis=1)'''
array([[1, 2, 3, 1, 2, 3],[4, 5, 6, 4, 5, 6]])
'''

对于处理混合维度的数组,使用np.vstack(垂直堆叠)和np.hstack(水平堆叠)函数更清楚:

x = np.array([1, 2, 3])
grid = np.array([[9, 8, 7],[6, 5, 4]])# 垂直堆叠数组
np.vstack([x, grid])'''
array([[1, 2, 3],[9, 8, 7],[6, 5, 4]])
'''# 水平堆叠数组
y = np.array([[99],[99]])
np.hstack([grid, y])'''
array([[ 9,  8,  7, 99],[ 6,  5,  4, 99]])
'''

类似地,np.dstack将沿第三个轴堆叠数组。

数组的分割

连接的反面是分割,它由函数np.splitnp.hsplitnp.vsplit实现。 对于其中的每一个,我们可以传递索引列表来提供分割点:

x = [1, 2, 3, 99, 99, 3, 2, 1]
x1, x2, x3 = np.split(x, [3, 5])
print(x1, x2, x3)# [1 2 3] [99 99] [3 2 1]

请注意,N个分割点会导致N+1个子数组。相关函数np.hsplitnp.vsplit是相似的:

grid = np.arange(16).reshape((4, 4))
grid'''
array([[ 0,  1,  2,  3],[ 4,  5,  6,  7],[ 8,  9, 10, 11],[12, 13, 14, 15]])
'''upper, lower = np.vsplit(grid, [2])
print(upper)
print(lower)'''
[[0 1 2 3][4 5 6 7]]
[[ 8  9 10 11][12 13 14 15]]
'''left, right = np.hsplit(grid, [2])
print(left)
print(right)'''
[[ 0  1][ 4  5][ 8  9][12 13]]
[[ 2  3][ 6  7][10 11][14 15]]
'''

类似地,np.dsplit将沿第三个轴分割数组。

数据科学 IPython 笔记本 9.4 NumPy 数组的基础相关推荐

  1. 数据科学 IPython 笔记本 9.5 NumPy 数组上的计算:通用函数

    9.5 NumPy 数组上的计算:通用函数 本节是<Python 数据科学手册>(Python Data Science Handbook)的摘录. 译者:飞龙 协议:CC BY-NC-S ...

  2. 数据科学 IPython 笔记本 9.2 NumPy 简介

    9.2 NumPy 简介 本节是<Python 数据科学手册>(Python Data Science Handbook)的摘录. 译者:飞龙 协议:CC BY-NC-SA 4.0 本章以 ...

  3. 数据科学 IPython 笔记本 9.1 NumPy

    9.1 NumPy 致谢:派生于 Olivier Grisel 分享的 scikit-learn 和 IPython 并行机器学习 译者:飞龙 协议:CC BY-NC-SA 4.0 NumPy 数组, ...

  4. 数据科学 IPython 笔记本 翻译完成

    原文:donnemartin/data-science-ipython-notebooks 译者:飞龙 协议:CC BY-NC-SA 4.0 欢迎任何人参与和完善:一个人可以走的很快,但是一群人却可以 ...

  5. 数据科学 IPython 笔记本 7.9 组合数据集:连接和附加

    7.9 组合数据集:连接和附加 原文:Combining Datasets: Concat and Append 译者:飞龙 协议:CC BY-NC-SA 4.0 本节是<Python 数据科学 ...

  6. 数据科学 IPython 笔记本 9.11 结构化数据:NumPy 的结构化数组

    9.11 结构化数据:NumPy 的结构化数组 本节是<Python 数据科学手册>(Python Data Science Handbook)的摘录. 译者:飞龙 协议:CC BY-NC ...

  7. 数据科学 IPython 笔记本 9.7 数组上的计算:广播

    9.7 数组上的计算:广播 本节是<Python 数据科学手册>(Python Data Science Handbook)的摘录. 译者:飞龙 协议:CC BY-NC-SA 4.0 我们 ...

  8. 数据科学 IPython 笔记本 8.7 密度和等高线图

    8.7 密度和等高线图 原文:Density and Contour Plots 译者:飞龙 协议:CC BY-NC-SA 4.0 本节是<Python 数据科学手册>(Python Da ...

  9. 数据科学 IPython 笔记本 8.3 Matplotlib 可视化

    8.3 Matplotlib 可视化 原文:Visualization with Matplotlib 译者:飞龙 协议:CC BY-NC-SA 4.0 本节是<Python 数据科学手册> ...

最新文章

  1. [文档].JLINK挂了怎么办?自己修![转载].JLINK_V8固件烧录和固件升级指导.pdf
  2. vue 获取当前时间 格式YYYY-MM-DD
  3. Linux查找文件 —— whereis 、 find、 locate、 which
  4. 图像处理与计算机视觉:基础,经典以及最近发展(4)图像处理与分析
  5. 以HANA为核心 SAP实时数据平台详解
  6. VMWARE VCSA 6.5安装过程
  7. 工作375-input readonly
  8. oracle查看会话(常规操作)
  9. 蓝桥杯 基础练习 高精度加法
  10. mr InputFormat类
  11. Day01 - 打开Linux大门
  12. 如何使用Mac DVDRipper Pro在mac上备份包括菜单和附加功能在内的完整的DVD
  13. 改2字节将Win XP Home变成Pro?!(zz)
  14. 【论文笔记】Contextual Diversity for Active Learning(ECCV2020)
  15. 存储服务器2012R2系统怎么搞文件共享,server2012r2文件共享局域网权限设置的方法...
  16. Python实战项目:代码秒抢红包详解
  17. 基于 Spring Boot 的停车场管理系统
  18. ARM模拟器-skyeye(天目)的安装和使用!
  19. 获取数据库最后一条数据
  20. unity沙子堆积_unity游戏动态体积雾沙尘暴管理渲染插件Dynamic Fogamp;Mist 6.5 - 素材巷...

热门文章

  1. (89)FPGA三分频设计,面试必问(十三)(第18天)
  2. (38)VHDL实现主从JK触发器
  3. (68)Verilog HDL系统函数和任务:$random
  4. (59)Verilog HDL测试激励:时钟激励1
  5. linux编译测试代码,rtc在linux上的测试代码
  6. hive 将null值替换为0_【Hive】数据倾斜
  7. java eclipse profile_在 Eclipse 中集成JProfiler 进行 JAVA 项目性能分析
  8. linux鼠标键盘被禁用了,debian squeeze下鼠标、键盘突然被系统禁用
  9. server sql 分组 去重 字符串拼接_SQL必知必会
  10. python搭建web服务