提交 7240f4a8 编写于 作者: W wizardforcel

2020-07-14 17:46:59

上级 5eb4cd2a
......@@ -2,7 +2,7 @@
Python 是一种多范式编程语言,已成为数据科学家进行数据分析,可视化和机器学习的首选语言。
您将首先学习如何为 Python 建立正确的数据分析环境。 在这里,您将学习安装正确的 Python 发行版,以及使用 Jupyter 笔记本和建立数据库。 之后,您将深入研究 Python 的 NumPy 软件包-Python 的强大扩展以及高级数学功能。 您将学习如何创建 NumPy 数组,以及如何使用不同的数组方法和函数。 然后,您将探索 Python 的 pandas 扩展,在那里您将学习数据的子集,并深入研究使用 pandas 的数据映射。 您还将学习通过对数据集进行排序和排序来管理它们。
您将首先学习如何为 Python 建立正确的数据分析环境。 在这里,您将学习安装正确的 Python 发行版,以及使用 Jupyter 笔记本和建立数据库。 之后,您将深入研究 Python 的 NumPy 软件包 -- Python 的强大扩展以及高级数学功能。 您将学习如何创建 NumPy 数组,以及如何使用不同的数组方法和函数。 然后,您将探索 Python 的 pandas 扩展,在那里您将学习数据的子集,并深入研究使用 pandas 的数据映射。 您还将学习通过对数据集进行排序和排序来管理它们。
到本书结尾,您将学习对数据进行索引和分组以进行复杂的数据分析和处理。
......
......@@ -40,9 +40,9 @@ Linux 安装必须通过命令行完成,但是对于那些熟悉 Linux 安装
# 探索 Jupyter 笔记本
在本节中,我们将探索 Jupyter Notebooks,这是我们将使用 Python 进行数据分析的主要工具。 我们将看到什么是 Jupyter Notebook,还将讨论 Markdown,这是我们在 Jupyter Notebook 中用于创建格式化文本的工具。 在 Jupyter 笔记本中,有两种类型的块。 有一些可执行的 Python 代码块,然后是带格式的,人类可读的文本块。
在本节中,我们将探索 Jupyter 笔记本,这是我们将使用 Python 进行数据分析的主要工具。 我们将看到什么是 Jupyter 笔记本,还将讨论 Markdown,这是我们在 Jupyter 笔记本中用于创建格式化文本的工具。 在 Jupyter 笔记本中,有两种类型的块。 有一些可执行的 Python 代码块,然后是带格式的,人类可读的文本块。
用户执行 Python 代码块,然后将结果直接插入文档中。 除非以同样的方式运行,否则代码块可以以任何顺序重新运行,而不必影响以后的块。 由于 Jupyter Notebook 基于 IPython,因此有一些附加功能,例如魔术功能。
用户执行 Python 代码块,然后将结果直接插入文档中。 除非以同样的方式运行,否则代码块可以以任何顺序重新运行,而不必影响以后的块。 由于 Jupyter 笔记本基于 IPython,因此有一些附加功能,例如魔术功能。
Anaconda 随附 Jupyter 笔记本。 Jupyter 笔记本允许纯文本与代码混合。 可以使用称为 **Markdown** 的语言格式化纯文本。 它以纯文本格式完成。 我们也可以插入段落。 以下示例是您在 Markdown 中看到的一些常见语法:
......@@ -52,7 +52,7 @@ Anaconda 随附 Jupyter 笔记本。 Jupyter 笔记本允许纯文本与代码
![](img/569e8dbc-0948-41f4-a911-f06b533ed491.png)
如您所见,它用尽了网络浏览器,例如 Chrome 或 Firefox,在这种情况下为 Chrome。 当我们开始 Jupyter Notebook 时,我们在文件浏览器中。 我们在一个新创建的目录`Untitled Folder`中。 在 Jupyter Notebook 中,有用于创建新 Notebook,文本文件和文件夹的选项。 如前面的屏幕截图所示,当前没有保存笔记本。 我们将需要一个 Python 笔记本,可以通过在以下屏幕快照中显示的 New 下拉菜单中选择 Python 选项来创建它。
如您所见,它用尽了网络浏览器,例如 Chrome 或 Firefox,在这种情况下为 Chrome。 当我们开始 Jupyter 笔记本时,我们在文件浏览器中。 我们在一个新创建的目录`Untitled Folder`中。 在 Jupyter 笔记本中,有用于创建新笔记本,文本文件和文件夹的选项。 如前面的屏幕截图所示,当前没有保存笔记本。 我们将需要一个 Python 笔记本,可以通过在以下屏幕快照中显示的“新建”下拉菜单中选择 Python 选项来创建它。
![](img/c622867b-9917-4cf6-8873-652cb09681be.png)
......@@ -78,11 +78,11 @@ Anaconda 随附 Jupyter 笔记本。 Jupyter 笔记本允许纯文本与代码
后台发生了什么? 发生的事情是有一个内核,它基本上是一个正在运行的 Python 会话,它跟踪我们所有的变量以及到目前为止发生的所有事情。 如果单击内核,则可以看到重新启动内核的选项。 这将基本上重新启动我们的 Python 会话。 我们最初警告说,通过重新启动内核,所有变量都将丢失。
重新启动内核后,似乎没有任何更改,但是如果我们运行第二个单元,则将产生错误,因为变量`trigger`不存在。 我们将需要首先运行上一个单元,以便该单元正常工作。 相反,如果我们不仅要重启内核,还要重启内核并重新运行所有单元,则需要单击 Restart & amp; 运行全部。 重新启动内核后,将重新运行所有单元块。 它可能看起来好像没有发生任何事情,但是我们已经从第一个开始,运行它,运行第二个单元格,然后运行第三个单元格,如下所示:
重新启动内核后,似乎没有任何更改,但是如果我们运行第二个单元,则将产生错误,因为变量`trigger`不存在。 我们将需要首先运行上一个单元,以便该单元正常工作。 相反,如果我们不仅要重启内核,还要重启内核并重新运行所有单元,则需要单击“重启并运行全部”。 重新启动内核后,将重新运行所有单元块。 它可能看起来好像没有发生任何事情,但是我们已经从第一个开始,运行它,运行第二个单元格,然后运行第三个单元格,如下所示:
![](img/2565c2e6-345d-4b1e-a1c2-7d3f5c795ea6.png)
我们也可以导入库。 例如,我们可以从 Matplotlib 导入模块。 在这种情况下,为了使 Matplotlib 在 Jupyter Notebook 中交互工作,我们将需要使用魔术函数,该魔术函数以%开头,魔术函数的名称以及需要传递给的任何类型的参数。 它。 稍后,我们将在详细信息中介绍这些内容,但首先让我们运行该单元格。`plt`现在已经加载,现在我们可以使用它了。 例如,在最后一个单元格中,我们将输入以下代码:
我们也可以导入库。 例如,我们可以从 Matplotlib 导入模块。 在这种情况下,为了使 Matplotlib 在 Jupyter 笔记本中交互工作,我们将需要使用魔术函数,该魔术函数以%开头,魔术函数的名称以及需要传递给的任何类型的参数。 它。 稍后,我们将在详细信息中介绍这些内容,但首先让我们运行该单元格。`plt`现在已经加载,现在我们可以使用它了。 例如,在最后一个单元格中,我们将输入以下代码:
![](img/cd197191-9798-46d6-9448-bed5424046a6.png)
......@@ -122,21 +122,21 @@ Anaconda 随附 Jupyter 笔记本。 Jupyter 笔记本允许纯文本与代码
# 探索 Jupyter 的替代品
现在,我们将考虑替代 Jupyter Notebooks。 我们将看:
现在,我们将考虑替代 Jupyter 笔记本。 我们将看:
* Jupyter QT 控制台
* 斯派德
* 圈地
* Spider
* Rodeo
* Python 解释器
* ptpython
我们将考虑的第一个替代方案是 Jupyter QT Console。 这是一个具有附加功能的 Python 解释器,专门用于数据分析。
我们将考虑的第一个替代方案是 Jupyter QT 控制台。 这是一个具有附加功能的 Python 解释器,专门用于数据分析。
以下屏幕截图显示了 Jupyter QT 控制台:
![](img/43fea253-2b02-483a-8fac-781c98e575b9.png)
它与 Jupyter Notebook 非常相似。 实际上,它实际上是 Jupyter Notebook 的控制台版本。 注意这里我们有一些有趣的语法。 我们有`In [1]`,然后假设您要键入一个命令,例如:
它与 Jupyter 笔记本非常相似。 实际上,它实际上是 Jupyter 笔记本的控制台版本。 注意这里我们有一些有趣的语法。 我们有`In [1]`,然后假设您要键入一个命令,例如:
```py
print ("Hello, world!")
......@@ -154,7 +154,7 @@ print ("Hello, world!")
![](img/f8fbe4b3-179f-4688-a522-102e7ab26012.png)
`In [2]`之后,我们看到`Out[2]`。 这是什么意思? 这是一种在会话中跟踪历史命令及其输出的方法。 要访问`In [42]`的命令,我们输入`_i42`。 因此,在这种情况下,如果要查看命令 2 的输入,请键入`i2`。 注意,它给我们一个字符串 1 +1。实际上,我们可以运行此字符串。
`In [2]`之后,我们看到`Out[2]`。 这是什么意思? 这是一种在会话中跟踪历史命令及其输出的方法。 要访问`In [42]`的命令,我们输入`_i42`。 因此,在这种情况下,如果要查看命令 2 的输入,请键入`i2`。 注意,它给我们一个字符串`1 + 1`。实际上,我们可以运行此字符串。
如果我们输入`eval`,然后输入`_i2`,请注意,它给我们提供的输出与原始命令`In [2]`相同。 现在`Out[2]`怎么样? 我们如何获取实际输出? 在这种情况下,我们要做的只是`_`,然后是输出的数量,例如 2。这应该给我们 2。因此,这为您提供了一种更方便的方法来访问历史命令及其输出。
......@@ -179,7 +179,7 @@ from sklearn.datasets import load_iris
```
这是用于数据分析的非常常见的数据集。 它通常用作评估训练模型的一种方法。 我们还将在此上使用 k-means 聚类:
这是用于数据分析的非常常见的数据集。 它通常用作评估训练模型的一种方法。 我们还将在此上使用 k 均值聚类:
```py
from sklearn.cluster import KMeans
......@@ -193,23 +193,23 @@ iris = load_iris()
```
现在,我们将在此数据集上训练 k-均值聚类方案:
现在,我们将在此数据集上训练 K 均值聚类方案:
```py
iris_clusters = KMeans(n_clusters = 3, init = "random").fit(iris.data)
```
键入函数时,我们可以立即查看文档。 例如,我知道 end clusters 参数的含义。 它实际上是函数中的原始文档字符串。 在这里,我希望聚类的数量为`3`,因为我知道此数据集中实际上有三个真实聚类。 既然已经训练了聚类方案,我们可以使用以下代码对其进行绘制:
键入函数时,我们可以立即查看文档。 例如,我知道`n_clusters`参数的含义。 它实际上是函数中的原始文档字符串。 在这里,我希望聚类的数量为`3`,因为我知道此数据集中实际上有三个真实聚类。 既然已经训练了聚类方案,我们可以使用以下代码对其进行绘制:
```py
plt.scatter(iris.data[:, 0], iris.data[:, 1], c = iris_clusters.labels_)
```
# 斯派德
# Spyder
Spyder 是与 Jupyter Notebook 或 Jupyter QT Console 不同的 IDE。 它集成了 NumPy,SciPy,Matplotlib 和 IPython。 它可以通过插件扩展,并且包含在 Anaconda 中。
Spyder 是与 Jupyter 笔记本或 Jupyter QT 控制台不同的 IDE。 它集成了 NumPy,SciPy,Matplotlib 和 IPython。 它可以通过插件扩展,并且包含在 Anaconda 中。
以下屏幕截图显示了 Spyder,这是一个用于数据分析和科学计算的实际 IDE:
......@@ -217,7 +217,7 @@ Spyder 是与 Jupyter Notebook 或 Jupyter QT Console 不同的 IDE。 它集成
Spyder Python 3.6
在右侧,您可以转到文件资源管理器以搜索要加载的新文件。 在这里,我们要打开`iris_kmeans.py`。 这是一个文件,其中包含我们之前在 Jupyter QT Console 中使用的所有命令。 请注意,在右侧,编辑器有一个控制台。 实际上就是 IPython 控制台,您将其视为 Jupyter QT 控制台。 我们可以通过单击 Run 选项卡来运行整个文件。 它将在控制台中运行,如下所示:
在右侧,您可以转到文件资源管理器以搜索要加载的新文件。 在这里,我们要打开`iris_kmeans.py`。 这是一个文件,其中包含我们之前在 Jupyter QT 控制台中使用的所有命令。 请注意,在右侧,编辑器有一个控制台。 实际上就是 IPython 控制台,您将其视为 Jupyter QT 控制台。 我们可以通过单击 Run 选项卡来运行整个文件。 它将在控制台中运行,如下所示:
![](img/fae7f8db-2540-43cf-a10f-76474350c5ff.png)
......@@ -247,7 +247,7 @@ n
到此结束我们对 Spyder 的讨论。
# 圈地
# Rodeo
Rodeo 是 Yhat 开发的 Python IDE,专门用于数据分析应用程序。 它旨在模拟在 R 用户中很流行的 RStudio IDE,并且可以从 Rodeo 的网站上下载。 基本的 Python 解释器的唯一优点是每个 Python 安装程序都包含它,如下所示:
......@@ -338,7 +338,7 @@ conda install selenium
```
如果`selenium`是我们感兴趣的软件包,则可以从 Internet 自动下载它,除非您具有 Anaconda 可以直接从您的系统直接安装的文件。
如果`selenium`是我们感兴趣的软件包,则可以从互联网自动下载它,除非您具有 Anaconda 可以直接从您的系统直接安装的文件。
要通过`pip`安装软件包,请使用以下命令:
......@@ -362,7 +362,7 @@ conda remove selenium
* 为 Python 安装 MySQL 连接器
* 创建,使用和删除数据库
为了使 MySQL 和 Python 一起使用,MySQL 连接器是必需的。 存在许多 SQL 数据库实现,尽管 MySQL 可能不是最简单的数据库管理系统,但它功能齐全,具有工业实力,在现实世界中很常见,而且它是免费和开源的,这意味着它是一个很好的学习工具。 您可以从 [MySQL 的网站](https://dev.mysql.com/downloads/)上获取 MySQL Community Edition,它是免费和开源的版本。
为了使 MySQL 和 Python 一起使用,MySQL 连接器是必需的。 存在许多 SQL 数据库实现,尽管 MySQL 可能不是最简单的数据库管理系统,但它功能齐全,具有工业实力,在现实世界中很常见,而且它是免费和开源的,这意味着它是一个很好的学习工具。 您可以从 [MySQL 的网站](https://dev.mysql.com/downloads/)上获取 MySQL 社区版,它是免费和开源的版本。
# 安装 MySQL
......@@ -374,7 +374,7 @@ Windows 用户可以直接从其网站安装 MySQL。 您还应该注意,MySQL
![](img/ee93dcc6-011a-4394-983e-12b44f1d65e8.png)
我建议您使用 MySQL Installer。 向下滚动,然后在寻找要下载的二进制文件时,请注意,第一个二进制文件表示网络社区。 这将是一个安装程序,可在您进行安装时从互联网上下载 MySQL。 请注意,它比另一个二进制文件小得多。 它基本上包括了您能够安装 MySQL 所需的一切。 如果您继续关注的话,我会建议您下载该文件。
我建议您使用 MySQL 安装程序。 向下滚动,然后在寻找要下载的二进制文件时,请注意,第一个二进制文件表示网络社区。 这将是一个安装程序,可在您进行安装时从互联网上下载 MySQL。 请注意,它比另一个二进制文件小得多。 它基本上包括了您能够安装 MySQL 所需的一切。 如果您继续关注的话,我会建议您下载该文件。
通常有可用的发行版。 这些应该是稳定的。 开发版本旁边是“常规版本”选项卡。 我建议您不要下载这些,除非您知道自己在做什么。
......
# 潜入 NumPY
# 潜入 NumPy
到目前为止,您应该已经安装了使用 Python 进行数据分析所需的一切。 现在让我们开始讨论 NumPy,这是用于管理数据和执行计算的重要软件包。 没有 NumPy,就不会使用 Python 进行任何数据分析,因此了解 NumPy 至关重要。 本章的主要目标是学习使用 NumPy 中提供的工具。
......@@ -14,11 +14,11 @@
# NumPy 数组
现在让我们讨论称为`ndarray`的 NumPy 数组。 这些不是您在 C 或 C ++中可能遇到的数组。 更好的模拟是 MATLAB 或 R 中的矩阵。 也就是说,它们的行为类似于数学对象,类似于数学矢量,矩阵或张量。 尽管它们可以存储诸如字符串之类的非数学信息,但它们的存在主要是为了管理和简化对数字数据的操作。`ndarray`在创建时被分配了特定的数据类型或`dtype`,并且数组中所有当前和将来的数据必须属于该`dtype`。 它们还具有多个维度,称为**轴**
现在让我们讨论称为`ndarray`的 NumPy 数组。 这些不是您在 C 或 C++ 中可能遇到的数组。 更好的模拟是 MATLAB 或 R 中的矩阵。 也就是说,它们的行为类似于数学对象,类似于数学向量,矩阵或张量。 尽管它们可以存储诸如字符串之类的非数学信息,但它们的存在主要是为了管理和简化对数字数据的操作。`ndarray`在创建时被分配了特定的数据类型或`dtype`,并且数组中所有当前和将来的数据必须属于该`dtype`。 它们还具有多个维度,称为**轴**
一维`ndarray`是一行数据; 这将是一个向量。 二维`ndarray`将是数据的平方,实际上是一个矩阵。 三维`ndarray`将是关键数据,就像张量一样。 允许任意数量的尺寸,但大多数`ndarray`都是一维或二维的。
`dtype`与基本 Python 语言中的类型相似,但 NumPy `dtype`与其他语言(例如 C,C ++或 Fortran)中看到的数据类型也很相似,因为它们的长度是固定的。`dtype`具有层次结构;`dtype`通常具有字符串描述符,后跟 2 的幂以决定`dtype`的大小。
`dtype`与基本 Python 语言中的类型相似,但 NumPy `dtype`与其他语言(例如 C,C++ 或 Fortran)中看到的数据类型也很相似,因为它们的长度是固定的。`dtype`具有层次结构;`dtype`通常具有字符串描述符,后跟 2 的幂以决定`dtype`的大小。
以下是常见的`dtype`列表:
......@@ -30,19 +30,19 @@
![](img/53e332d4-6601-4803-919f-c1e772c4b24f.png)
如果我们查看`dtype`,就会看到它是`int8`,即 8 位整数。 我们还可以创建一个由 16 位浮点数填充的数组。 该数组看起来类似于整数数组。 1s 的末尾有一个圆点; 这有点表明包含的数据是浮点而不是整数。
如果我们查看`dtype`,就会看到它是`int8`,即 8 位整数。 我们还可以创建一个由 16 位浮点数填充的数组。 该数组看起来类似于整数数组。 1 的末尾有一个圆点; 这有点表明包含的数据是浮点而不是整数。
让我们创建一个填充无符号整数的数组:
![](img/3e9f87fd-7331-4399-9396-881a8c917e2d.png)
同样,它们为 1,看起来与我们以前的相似,但现在让我们尝试更改一些数据。 例如,我们可以将数组`int_ones`中的数字更改为-1,就可以了。 但是,如果我尝试将其以无符号整数更改为-1,则最终会得到 255。
同样,它们为 1,看起来与我们以前的相似,但现在让我们尝试更改一些数据。 例如,我们可以将数组`int_ones`中的数字更改为 -1,就可以了。 但是,如果我尝试将其以无符号整数更改为 -1,则最终会得到 255。
让我们创建一个填充字符串的数组:
![](img/137bc79a-59ee-44a6-a90f-c8503ecfa0a3.png)
我们此处未指定`dtype`参数,因为通常会猜测`dtype`。 通常会做出一个很好的猜测,但是并不能保证。 例如,在这里我想为该数组的内容分配一个新值`Waldo`。 现在,此`dtype`表示您的字符串长度不能超过四个。 虽然`Waldo`有五个字符,所以当我们更改数组并更改其内容时,我们以 Wald 而不是`Waldo`结尾。 这是因为它不能超过五个字符。 只需要前四个:
我们此处未指定`dtype`参数,因为通常会猜测`dtype`。 通常会做出一个很好的猜测,但是并不能保证。 例如,在这里我想为该数组的内容分配一个新值`Waldo`。 现在,此`dtype`表示您的字符串长度不能超过四个。 虽然`Waldo`有五个字符,所以当我们更改数组并更改其内容时,我们以`Wald`而不是`Waldo`结尾。 这是因为它不能超过五个字符。 只需要前四个:
![](img/9d488485-848b-4c1c-bfaa-6cd76eb8fc72.png)
......@@ -52,7 +52,7 @@
除了`dtype`对象之外,NumPy 还引入了特殊的数值:`nan``inf`。 这些可以在数学计算中出现。 **不是数字**`NaN`)。 它表明应为数字的值实际上不是数学定义的。 例如,`0/0`产生`nan`。 有时`nan`也用于表示缺少的信息; 例如,Pandas 就用这个。`inf`表示任意大的数量,因此在实践中,它表示比计算机可以想象的任何数量大的数量。 还定义了`-inf`,它的意思是任意小。 如果数字运算爆炸,即迅速增长而没有边界,则可能会发生这种情况。
从未等于`nan`; 没有定义的事物等于其他事物是没有意义的。 您需要使用 NumPy 函数`isnan`来识别`nan`。 尽管`==`符号不适用于`nan`,但适用于`inf`。 就是说,最好还是使用函数有限或`inf`来区分有限值和无限值。 定义了涉及`nan``inf`的算法,但请注意,它可能无法满足您的需求。 定义了一些特殊功能,以帮助避免出现`nan``inf`时出现的问题。 例如,`nan` sum 在忽略`nan`的同时计算可迭代对象的总和。 您可以在 NumPy 文档中找到此类功能的完整列表。 使用它们时,我只会提及它们。
从未等于`nan`; 没有定义的事物等于其他事物是没有意义的。 您需要使用 NumPy 函数`isnan`来识别`nan`。 尽管`==`符号不适用于`nan`,但适用于`inf`。 就是说,最好还是使用函数有限或`inf`来区分有限值和无限值。 定义了涉及`nan``inf`的算法,但请注意,它可能无法满足您的需求。 定义了一些特殊功能,以帮助避免出现`nan``inf`时出现的问题。 例如,`nansum` 在忽略`nan`的同时计算可迭代对象的总和。 您可以在 NumPy 文档中找到此类功能的完整列表。 使用它们时,我只会提及它们。
现在让我们来看一个例子:
......@@ -66,7 +66,7 @@
![](img/27a62731-2f47-4664-98b7-577852953fa5.png)
我们将遍历`vec2`的每个可能值,并打印`i == np.inf``i == -np.inf`的结果以及 I 是否等于`nan``i == np.nan`的结果。 我们得到的是一张清单;`inf``-inf`的前两个块很好,但是这个`nan`不好。 我们希望它检测到`nan`,但它没有这样做。 因此,让我们尝试使用是`nan`函数:
我们将遍历`vec2`的每个可能值,并打印`i == np.inf``i == -np.inf`的结果以及`i`是否等于`nan``i == np.nan`的结果。 我们得到的是一张清单;`inf``-inf`的前两个块很好,但是这个`nan`不好。 我们希望它检测到`nan`,但它没有这样做。 因此,让我们尝试使用是`nan`函数:
![](img/5a78d47d-efda-4805-89cc-7184f5541f39.png)
......@@ -92,13 +92,13 @@
![](img/45324bdd-4926-41d6-aaed-0e6efdb562c7.png)
但是,如果我们使用函数`nansum`,则 nans 将被忽略,我们将获得合理的值 4。
但是,如果我们使用函数`nansum`,则`nan`将被忽略,我们将获得合理的值 4。
# 创建 NumPy 数组
现在,我们已经讨论了 NumPy 数据类型,并简要介绍了 NumPy 数组,下面让我们讨论如何创建 NumPy 数组。 在本节中,我们将使用各种函数创建 NumPy 数组。 有一些函数可以创建所谓的空`ndarray`; 用于创建`ndarray`的函数,其中填充了 0、1 或随机数; 以及使用数据创建`ndarray`的功能。 我们将讨论所有这些,以及从磁盘保存和加载 NumPy 数组。 有几种创建数组的方法。 一种方法是使用数组函数,在此我们提供一个可迭代的对象或一个可迭代的对象列表,从中将生成一个数组。
我们将使用列表列表来执行此操作,但是这些列表可以是元组,元组的元组甚至其他数组的列表。 还有一些方法可以自动创建充满数据的数组。 例如,我们可以使用诸如`ones``zeros``randn`之类的功能; 后者填充了随机生成的数据。 这些数组需要传递一个元组,该元组确定数组的形状,即数组具有多少维以及每个维的长度。 每个创建的数组都被认为是空的,不包含任何感兴趣的数据。 这通常是垃圾数据,由创建阵列的内存位置中的任何位组成。
我们将使用列表列表来执行此操作,但是这些列表可以是元组,元组的元组甚至其他数组的列表。 还有一些方法可以自动创建充满数据的数组。 例如,我们可以使用诸如`ones``zeros``randn`之类的功能; 后者填充了随机生成的数据。 这些数组需要传递一个元组,该元组确定数组的形状,即数组具有多少维以及每个维的长度。 每个创建的数组都被认为是空的,不包含任何感兴趣的数据。 这通常是垃圾数据,由创建数组的内存位置中的任何位组成。
我们可以根据需要指定`dtype`参数,但如果不指定,则可以猜测`dtype`或浮点数。 请注意下表中的最后一行:
......@@ -108,7 +108,7 @@
# 创建 ndarray
在下面的笔记本中,我们创建一个`ndarray`。 我们要做的第一件事是创建一个 1s 的向量。 注意正在传递的元组; 它仅包含一个数字`5`。 因此,它将是具有五个元素的一维`ndarray`
在下面的笔记本中,我们创建一个`ndarray`。 我们要做的第一件事是创建一个 1 的向量。 注意正在传递的元组; 它仅包含一个数字`5`。 因此,它将是具有五个元素的一维`ndarray`
![](img/12e69768-3944-4664-b6c5-4458046f4bed.png)
......@@ -144,7 +144,7 @@
我们传递的第一个数字是行数,第二个数字是列数。 您可以传递第三个数字来确定平板的数量,第四个,第五个等等,以指定所需的维数以及每个维的长度。
现在,我们将创建 2 x 2 个具有所选名称的矩阵,以及 2 x 2 x 2 个包含数字的数组。 因此,这是一个仅包含名称的矩阵:
现在,我们将创建`2 x 2`个具有所选名称的矩阵,以及`2 x 2 x 2`个包含数字的数组。 因此,这是一个仅包含名称的矩阵:
![](img/bd1788b5-bd18-45d8-bb65-2965bc0332fb.png)
......@@ -220,7 +220,7 @@
这些功能与用于保存`ndarray`的功能紧密一致。 您将需要在 Python 中保存生成的`ndarray`。 如果要从文本文件加载,请注意,不必为创建`ndarray`而由 NumPy 创建数组。 如果您保存到 CSV,则可以使用文本编辑器或 Excel 创建 NumPy `ndarray`。 然后,您可以将它们加载到 Python 中。 我假设您正在加载的文件中的数据适合`ndarray`; 也就是说,它具有正方形格式,并且仅由一种类型的数据组成,因此不包含字符串和数字。
可以通过`ndarray`处理多类型的数据,但是此时您应该使用 pandas DataFrame,我们将在后面的部分中进行讨论。 因此,如果我想加载刚刚创建的文件的内容,可以使用`loadtxt`函数进行加载,结果如下:
可以通过`ndarray`处理多类型的数据,但是此时您应该使用 pandas 数据帧,我们将在后面的部分中进行讨论。 因此,如果我想加载刚刚创建的文件的内容,可以使用`loadtxt`函数进行加载,结果如下:
![](img/f28be513-9207-4b9c-bb2f-79cf5e1e108a.png)
......
......@@ -24,7 +24,7 @@
![](img/af0927e8-301a-42be-9310-3d7474e8d22b.png)
注意,我们创建的是三维数组。 现在,这个数组有点复杂,所以让我们使用二维 3 x 3 数组代替 :
注意,我们创建的是三维数组。 现在,这个数组有点复杂,所以让我们使用二维`3 x 3`数组代替 :
![](img/4b7191f0-9604-4d41-ade1-a94f825cc394.png)
......@@ -68,7 +68,7 @@
![](img/8a40d17d-96b8-4941-9e5a-b021835166e4.png)
我们可以转到更复杂的三维数组,并查看类似的切片方案。 例如,这是一个 2 x 2 x 2 的角落立方体:
我们可以转到更复杂的三维数组,并查看类似的切片方案。 例如,这是一个`2 x 2 x 2`的角落立方体:
![](img/71d20c8d-94ee-42a8-bcd0-5873b5436fa9.png)
......@@ -94,7 +94,7 @@
![](img/ac3484b4-148f-429a-8a45-8438a9099552.png)
Wayne 不包括在选择中,这是为执行该索引而生成的数组:
`Wayne`不包括在选择中,这是为执行该索引而生成的数组:
![](img/e8020cee-2b6f-4749-a0fa-0853b8d9ccdf.png)
......@@ -124,7 +124,7 @@ Wayne 不包括在选择中,这是为执行该索引而生成的数组:
因此,我实际上已经编写了一些代码,可以实际演示哪些元素将显示在新数组中,即,原始数组中的坐标对新数组中的元素而言是什么。
例如,我们得到的是一个二维矩阵 2 x 2 x2。如果我们想知道切片对象的第二行,第二列和第一个平板中的内容,则可以使用如下代码 :
例如,我们得到的是一个二维矩阵`2 x 2 x 2`。如果我们想知道切片对象的第二行,第二列和第一个平板中的内容,则可以使用如下代码 :
![](img/6775c4bd-a18b-4f5d-82a1-054281393b62.png)
......@@ -132,13 +132,13 @@ Wayne 不包括在选择中,这是为执行该索引而生成的数组:
# 扩展数组
连接功能允许使用屏幕上显示的语法沿公共轴将数组绑定在一起。 该方法要求阵列沿未用于绑定的轴具有相似的形状。 结果就是全新的`ndarray`,这是将阵列粘合在一起的产物。 为此,还存在其他类似功能,例如堆栈。 我们不会涵盖所有内容。
连接功能允许使用屏幕上显示的语法沿公共轴将数组绑定在一起。 该方法要求数组沿未用于绑定的轴具有相似的形状。 结果就是全新的`ndarray`,这是将数组粘合在一起的产物。 为此,还存在其他类似功能,例如堆栈。 我们不会涵盖所有内容。
假设我们想向`arr2`添加更多行。 使用以下代码执行此操作:
![](img/e700972d-12c9-4034-b0d3-306ec2834ddc.png)
我们创建一个全新的阵列。 在这种情况下,我们不需要使用`copy`方法。 结果如下:
我们创建一个全新的数组。 在这种情况下,我们不需要使用`copy`方法。 结果如下:
![](img/ff450802-d16c-42d4-93fa-e7185eaa62b5.png)
......@@ -188,7 +188,7 @@ NumPy 数组的算术总是按组件进行的。 这意味着,如果我们有
到目前为止,我们已经处理了两个形状相同的数组。 实际上,这不是必需的。 尽管我们不一定要添加两个任意形状的数组,但是在某些情况下,我们可以合理地对不同形状的数组执行算术运算。 从某种意义上说,较小数组中的信息被视为属于相同形状但具有重复值的数组。 让我们看看实际的广播行为。
现在,回想一下数组`arr1` 3 x 3 x 3; 也就是说,它具有三行,三列和三个平板。 在这里,我们创建一个对象`arr3`
现在,回想一下数组`arr1``3 x 3 x 3`; 也就是说,它具有三行,三列和三个平板。 在这里,我们创建一个对象`arr3`
![](img/3933075d-3add-41e7-ab02-a7ddac1faf9e.png)
......@@ -196,7 +196,7 @@ NumPy 数组的算术总是按组件进行的。 这意味着,如果我们有
![](img/cc993b4c-c0a0-4b16-bbb7-a5fe7227e792.png)
我将第 0 列和第 2 列设为 0,将中间列设为 1.因此,结果是我有效地选择了中间列并将其他两列设置为 0。有效地复制了该对象,因此好像我将`arr1`乘以一个对象一样,其中第一列为 0,第三列为 0,第二列为 1。
我将第 0 列和第 2 列设为 0,将中间列设为 1因此,结果是我有效地选择了中间列并将其他两列设置为 0。有效地复制了该对象,因此好像我将`arr1`乘以一个对象一样,其中第一列为 0,第三列为 0,第二列为 1。
现在,让我们看看如果切换此对象的尺寸会发生什么? 因此,现在它具有一列,一个平板和三行:
......@@ -222,13 +222,13 @@ NumPy 数组的算术总是按组件进行的。 这意味着,如果我们有
![](img/f7a9f0cd-719f-4d06-bdda-0b7dc921a6e2.png)
我说`arr4``arr3`,我们绕着轴切换。 因此,轴 0 仍将是轴 0,但轴 1 将是旧阵列的轴 2,而轴 2 将是旧阵列的轴 1。
我说`arr4``arr3`,我们绕着轴切换。 因此,轴 0 仍将是轴 0,但轴 1 将是旧数组的轴 2,而轴 2 将是旧数组的轴 1。
现在,让我们看看其他示例。 让我们看一下重塑的演示。 因此,我们要做的第一件事是创建一个由八个元素组成的数组:
![](img/fbe3c803-540a-4bd0-8173-4a9a4cccb241.png)
我们可以重新排列此数组的内容,使其适合其他形状的数组。 现在,需要的是新数组具有与原始数组相同数量的元素。 因此,创建一个 2 x 4 数组,如下所示:
我们可以重新排列此数组的内容,使其适合其他形状的数组。 现在,需要的是新数组具有与原始数组相同数量的元素。 因此,创建一个`2 x 4`数组,如下所示:
![](img/9ff57a7c-299e-44f2-9aae-7bfbcba58140.png)
......@@ -238,7 +238,7 @@ NumPy 数组的算术总是按组件进行的。 这意味着,如果我们有
您可以通过查看此数组的逻辑方式来猜测。
现在让我们看一些更复杂的线性代数功能。 让我们从 Scikit-Learn 库的数据集模块中加载一个名为`load_iris`的函数,以便我们可以查看经典的 Iris 数据集:
现在让我们看一些更复杂的线性代数功能。 让我们从 Sklearn 库的数据集模块中加载一个名为`load_iris`的函数,以便我们可以查看经典的鸢尾花数据集:
![](img/97bf54b1-56e6-4936-9afa-b1bf10da93a9.png)
......@@ -252,21 +252,21 @@ NumPy 数组的算术总是按组件进行的。 这意味着,如果我们有
我还想创建一个仅包含鸢尾花副本最后一列的新数组,并创建另一个包含其余列和全为 1 的列的数组。
现在,我们将创建一个与矩阵乘积相对应的新数组。 所以我说 X 平方是 X 转置并乘以 X,这就是结果数组:
现在,我们将创建一个与矩阵乘积相对应的新数组。 所以我说`X`平方是`X`转置并乘以`X`,这就是结果数组:
![](img/bf272c7e-734d-4e2c-8f2c-1d1e5d90038e.png)
它是 4 x4。现在让我们得到一个逆矩阵 X 的平方。
它是`4 x 4`。现在让我们得到一个逆矩阵`X`的平方。
这将是矩阵逆:
![](img/0f98403f-4fa3-4fba-aec1-c893f18addc5.png)
然后,我取这个逆,然​​后将其乘以 X 的转置乘积与矩阵 Y 的乘积,矩阵 Y 是我之前创建的那个单列矩阵。 结果如下:
然后,我取这个逆,然​​后将其乘以`X`的转置乘积与矩阵`Y`的乘积,矩阵`Y`是我之前创建的那个单列矩阵。 结果如下:
![](img/793b3b23-eb4d-41b2-92a3-241e2ee05250.png)
这不是任意的计算顺序; 它实际上对应于我们求解线性模型系数的方式。 原始矩阵`y = iris_cp[:, 3]`对应于我们要使用 X 的内容预测的变量的值; 但是现在,我只想演示一些线性代数。 当遇到的函数时,您现在就知道自己编写此函数所需的所有代码。
这不是任意的计算顺序; 它实际上对应于我们求解线性模型系数的方式。 原始矩阵`y = iris_cp[:, 3]`对应于我们要使用`X`的内容预测的变量的值; 但是现在,我只想演示一些线性代数。 当遇到的函数时,您现在就知道自己编写此函数所需的所有代码。
我们在数据分析中经常要做的另一件事是找到矩阵的 SVD 分解,并且在此线性代数函数中提供了 SVD 分解:
......@@ -306,11 +306,11 @@ NumPy `ndarray`函数包含一些有助于完成常见任务的方法,例如
![](img/ba2fae42-8863-4c5c-a04b-580ad14dc931.png)
我们可以将阵列展平,使其从 4 x 4 阵列变为一维阵列,如下所示:
我们可以将数组展平,使其从`4 x 4`数组变为一维数组,如下所示:
![](img/90aef03f-ec71-4f3d-80e8-2f9953006162.png)
我们还可以使用 fill 方法填充一个空数组。 在这里,我创建了一个用于字符串的空数组,并用字符串`Carlos`填充了它:
我们还可以使用`fill`方法填充一个空数组。 在这里,我创建了一个用于字符串的空数组,并用字符串`Carlos`填充了它:
![](img/8ed9442b-16e1-4ccc-a42a-888d6d544fa7.png)
......@@ -337,9 +337,9 @@ NumPy `ndarray`函数包含一些有助于完成常见任务的方法,例如
![](img/fefb42e0-e214-456a-b32a-74909478cd87.png)
# 用 ufuncs 进行矢量化
# 用`ufuncs`进行向量化
ufunc 是专门用于数组的 NumPy 函数; 特别地,它们支持向量化。 向量化函数按组件方式应用于数组的元素。 这些通常是高度优化的功能,可以在较快的语言(例如 C)的后台运行。
`ufunc`是专门用于数组的 NumPy 函数; 特别地,它们支持向量化。 向量化函数按组件方式应用于数组的元素。 这些通常是高度优化的功能,可以在较快的语言(例如 C)的后台运行。
在下面,我们看到一些常见的`ufuncs`,其中许多是数学上的:
......@@ -359,9 +359,9 @@ ufunc 是专门用于数组的 NumPy 函数; 特别地,它们支持向量化
# 自定义功能
如前所述,我们可以创建自己的`ufuncs`。 创建`ufuncs`的一种方法是使用现有的`ufuncs`矢量化操作,数组方法等(即 Numpy 的所有现有基础结构)来创建一个函数,该函数逐个组件地生成我们想要的结果。 假设由于某些原因我们不想这样做。 如果我们有一个现有的 Python 函数,而只想对该函数进行矢量化处理,以便将其应用于`ndarray`组件,则可以使用 NumPy 的 vectorize 函数创建该函数的新矢量化版本。 Vectorize 将功能作为输入,并将功能的矢量化版本作为输出。
如前所述,我们可以创建自己的`ufuncs`。 创建`ufuncs`的一种方法是使用现有的`ufuncs`向量化操作,数组方法等(即 Numpy 的所有现有基础结构)来创建一个函数,该函数逐个组件地生成我们想要的结果。 假设由于某些原因我们不想这样做。 如果我们有一个现有的 Python 函数,而只想对该函数进行向量化处理,以便将其应用于`ndarray`组件,则可以使用 NumPy 的`vectorize`函数创建该函数的新向量化版本。 `vectorize`将功能作为输入,并将功能的向量化版本作为输出。
如果您不关心速度,可以使用 Vectorize,但是 Vectorize 创建的功能不一定很快。 实际上,前一种方法(使用 NumPy 的现有功能和基础结构来创建您的矢量化功能)可将`ufuncs`的生成速度提高许多倍。
如果您不关心速度,可以使用`vectorize`,但是`vectorize`创建的功能不一定很快。 实际上,前一种方法(使用 NumPy 的现有功能和基础结构来创建您的向量化功能)可将`ufuncs`的生成速度提高许多倍。
我们要做的第一件事是定义一个适用于单个标量值的函数。 它的作用是截断,因此如果一个数字小于零,则该数字将替换为零:
......@@ -375,7 +375,7 @@ ufunc 是专门用于数组的 NumPy 函数; 特别地,它们支持向量化
![](img/6cc5d3ea-e108-4b80-84b6-60cc1a24d15f.png)
我们需要做的是创建一个`ufunc`,其功能与原始功能相同。 因此,我们使用 vectorize 并可以创建可以按预期工作的 vectorized 版本,但效率不高:
我们需要做的是创建一个`ufunc`,其功能与原始功能相同。 因此,我们使用 vectorize 并可以创建可以按预期工作的向量化版本,但效率不高:
![](img/bcddac11-fa34-4ee4-b31b-c01e539951bc.png)
......@@ -383,7 +383,7 @@ ufunc 是专门用于数组的 NumPy 函数; 特别地,它们支持向量化
![](img/380190d1-54f2-4971-8bef-0e5f9196d14b.png)
让我们比较这两个函数的速度。 以下是使用 vectorize 创建的矢量化版本:
让我们比较这两个函数的速度。 以下是使用`vectorize`创建的向量化版本:
![](img/a4a3a475-cc94-4a82-88c4-06b7329e39c1.png)
......@@ -395,4 +395,4 @@ ufunc 是专门用于数组的 NumPy 函数; 特别地,它们支持向量化
# 摘要
在本章中,我们从显式选择数组中的元素开始。 我们研究了高级索引编制和扩展数组。 我们还用数组介绍了一些算术和线性代数。 我们讨论了使用数组方法和函数以及`ufuncs`的矢量化。 在下一章中,我们将开始学习另一个有影响力的软件包,称为 **Pandas**
\ No newline at end of file
在本章中,我们从显式选择数组中的元素开始。 我们研究了高级索引编制和扩展数组。 我们还用数组介绍了一些算术和线性代数。 我们讨论了使用数组方法和函数以及`ufuncs`的向量化。 在下一章中,我们将开始学习另一个有影响力的软件包,称为 **Pandas**
\ No newline at end of file
......@@ -12,7 +12,7 @@ pandas 向 Python 引入了两个关键对象,序列和数据帧,后者可
![](img/1e8c0c05-3a69-4331-8685-aa11ae55feee.png)
我们将同时加载 NumPy 和 pandas,我们将研究读取 NumPy 和 pandas 的 CSV 文件。 实际上,我们可以在 NumPy 中加载 CSV 文件,并且它们可以具有不同类型的数据,但是为了管理此类文件,您需要创建自定义`dtype`以类似于此类数据。 因此,这里有一个 CSV 文件`iris.csv`,其中包含 Iris 数据集。
我们将同时加载 NumPy 和 pandas,我们将研究读取 NumPy 和 pandas 的 CSV 文件。 实际上,我们可以在 NumPy 中加载 CSV 文件,并且它们可以具有不同类型的数据,但是为了管理此类文件,您需要创建自定义`dtype`以类似于此类数据。 因此,这里有一个 CSV 文件`iris.csv`,其中包含鸢尾花数据集。
现在,如果我们希望加载该数据,则需要考虑以下事实:每一行的数据不一定都是同一类型的。 特别是最后一列是针对物种的,它不是数字,而是字符串。 因此,我们需要创建一个自定义`dtype`,在此处执行此操作,以调用此新的`dtype`模式:
......
......@@ -36,7 +36,7 @@
![](img/f597919b-359d-4d02-a098-442b90b23121.png)
现在,让我们应用自定义`ufunc`。 在这里,我们使用装饰器符号。 在下一个屏幕截图中,让我们看看使用此截断函数的量化版本,数组然后将其应用于`srs1`时会发生什么,如下所示:
现在,让我们应用自定义`ufunc`。 在这里,我们使用装饰器符号。 在下一个屏幕截图中,让我们看看使用此截断函数的量化版本,数组然后将其应用于`srs1`时会发生什么,如下所示:
![](img/f5d73fed-b5c3-49b0-8a7e-4c0f187c8be6.png)
......@@ -68,7 +68,7 @@
![](img/4ab5fcba-1a5b-4fc6-92fb-f0c3d827aa87.png)
我们可以定义一个量化函数来执行此操作,但是请注意,通过使用 apply,我们设法保留了序列结构。 让我们创建一个新系列`srs3`,如下所示:
我们可以定义一个量化函数来执行此操作,但是请注意,通过使用 apply,我们设法保留了序列结构。 让我们创建一个新系列`srs3`,如下所示:
![](img/6448ba68-fdf2-4c13-9aa9-74dd95d66292.png)
......@@ -82,7 +82,7 @@
DataFrame 之间的算术与序列或 NumPy 数组算术具有某些相似之处。 如您所料,两个数据帧或一个数据帧与一个缩放器之间的算术工作; 但是数据帧和系列之间的算术运算需要谨慎。 必须牢记的是,涉及数据帧的算法首先应用于数据帧的列,然后再应用于数据帧的行。 因此,数据帧中的列将与单个标量,具有与该列同名的索引的系列元素或其他涉及的数据帧中的列匹配。 如果有序列或数据帧的元素找不到匹配项,则会生成新列,对应于不匹配的元素或列,并填充 Nan。
# 使用数据帧进行量化
# 使用数据帧进行量化
向量化可以应用于数据帧。 给定一个数据帧时,许多 NumPy `ufuncs`(例如平方根或`sqrt`)将按预期工作; 实际上,当给定数据帧时,它们仍可能返回数据帧。 也就是说,这不能保证,尤其是在使用通过 vectorize 创建的自定义`ufunc`时。 在这种情况下,他们可能会返回`ndarray`。 虽然这些方法适用于具有通用数据类型的数据帧,但是不能保证它们将适用于所有数据帧。
......@@ -112,7 +112,7 @@ DataFrame 之间的算术与序列或 NumPy 数组算术具有某些相似之处
![](img/441b9928-2a05-4868-bef2-ceda07302961.png)
现在让我们看一下向量化。 平方根函数是 NumPy 的量化函数,可在数据帧上按预期工作:
现在让我们看一下向量化。 平方根函数是 NumPy 的量化函数,可在数据帧上按预期工作:
![](img/abd19d26-34d7-4089-813c-fc8eaf08dae6.png)
......@@ -248,4 +248,4 @@ DataFrame 之间的算术与序列或 NumPy 数组算术具有某些相似之处
# 摘要
在本章中,我们介绍了 Pandas DataFrames,矢量化和数据帧函数应用程序的算术运算。 我们还学习了如何通过删除或填写缺失的信息来处理 pandas DataFrame 中的缺失数据。 在下一章中,我们将研究数据分析项目中的常见任务的排序,排序,和。
\ No newline at end of file
在本章中,我们介绍了 Pandas DataFrames,向量化和数据帧函数应用程序的算术运算。 我们还学习了如何通过删除或填写缺失的信息来处理 pandas DataFrame 中的缺失数据。 在下一章中,我们将研究数据分析项目中的常见任务的排序,排序,和。
\ No newline at end of file
......@@ -118,7 +118,7 @@
它最初是由 MATLAB 随附的绘图系统启发的,尽管现在它是它自己的野兽,但不一定是最容易使用的。 Matplotlib 具有许多功能,在本课程中,我们将只涉及其绘制的表面。 在本节中,我们将讨论在特定实例之外使用 Python 进行可视化的程度,即使可视化是从初始探索到呈现结果的数据分析的关键部分。 我建议寻找其他资源以了解有关可视化的更多信息。 例如,Packt 有专门针对该主题的视频课程。
无论如何,如果我们希望能够使用 pandas 方法进行绘图,则必须安装 Matplotlib 并可以使用。 如果您正在使用 Jupyter Notebook 或 Jupyter QtConsole 或其他基于 IPython 的环境,则建议运行`pylab`魔术。
无论如何,如果我们希望能够使用 pandas 方法进行绘图,则必须安装 Matplotlib 并可以使用。 如果您正在使用 Jupyter 笔记本或 Jupyter QtConsole 或其他基于 IPython 的环境,则建议运行`pylab`魔术。
# 绘图方法
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册