使用 Pandas 处理数据

当我们谈论管理数据时,看到表格形式呈现的数据是不可避免的。带有列标题,有时还有行名,这使得理解数据更容易。事实上,我们经常会看到不同类型的数据共存于一个表格中。例如,在食谱原料的表格中,我们有作为数字的数量和作为字符串的名称。在 Python 中,我们有 pandas 库来帮助我们处理表格数据。

完成本教程后,你将学到:

  • Pandas 库提供了什么
  • Pandas 中的 DataFrame 和 Series 是什么
  • 如何对 DataFrame 和 Series 进行超越琐碎数组运算的操作

开启您的项目,阅读我的新书《Python for Machine Learning》,其中包含分步教程和所有示例的Python源代码文件。

让我们开始吧!

使用 Pandas 处理数据
照片由 Mark de Jong 拍摄。部分权利保留。

概述

本教程分为五个部分

  • DataFrame 和 Series
  • DataFrame 中的基本函数
  • 操作 DataFrame 和 Series
  • DataFrame 中的聚合
  • 在 Pandas 中处理时间序列数据

DataFrame 和 Series

首先,让我们从一个示例数据集开始。我们将导入 pandas 并读取 美国空气污染物排放数据 到 DataFrame 中。

这是每年的污染物排放量表格,其中包含污染物的种类和每年的排放量信息。

这里我们演示了 pandas 的一个有用特性:你可以使用 `read_csv()` 读取 CSV 文件,或者像上面一样使用 `read_excel()` 读取 Excel 文件。文件名可以是本地文件,也可以是可供下载文件的 URL。我们从美国环境保护署的网站上了解到这个 URL。我们知道哪个工作表包含数据以及数据从哪一行开始,因此在 `read_excel()` 函数中使用了额外的参数。

上面创建的 pandas 对象是一个 DataFrame,以表格形式呈现。与 NumPy 类似,Pandas 中的数据组织在数组中。但是 Pandas 为列分配数据类型,而不是整个数组。这允许在同一数据结构中包含不同类型的数据。我们可以通过调用 DataFrame 的 `info()` 函数来检查数据类型

或者我们也可以获取一个 pandas Series 类型的类型

在 pandas 中,DataFrame 是一张表,而 Series 是表中的一列。这个区别很重要,因为 DataFrame 后面的数据是二维数组,而 Series 是一维数组。

类似于 NumPy 中的花式索引,我们可以从一个 DataFrame 中提取列来创建另一个 DataFrame。

或者,如果传递给字符串而不是列名列表,则我们提取 DataFrame 中的一列作为 Series。

DataFrame 中的基本函数

Pandas 功能丰富。对表或列的许多基本操作都作为 DataFrame 或 Series 上定义的函数提供。例如,我们可以使用以下方法查看表中包含的污染物列表:

同样,我们可以找到 Series 的平均值(`mean()`)、标准差(`std()`)、最小值(`min()`)和最大值(`max()`)。

但实际上,我们更可能使用 `describe()` 函数来探索新的 DataFrame。由于本例中的 DataFrame 列数过多,因此最好对 `describe()` 的结果 DataFrame 进行转置。

确实,`describe()` 生成的 DataFrame 可以帮助我们了解数据。从中,我们可以看出有多少缺失数据(通过查看计数),数据是如何分布的,是否存在异常值等等。

想开始学习机器学习 Python 吗?

立即参加我为期7天的免费电子邮件速成课程(附示例代码)。

点击注册,同时获得该课程的免费PDF电子书版本。

操作 DataFrame 和 Series

类似于 NumPy 中的布尔索引,我们可以从 DataFrame 中提取一个行的子集。例如,这是选择一氧化碳排放数据的方法:

正如您可能预期的那样,`==` 运算符将 Series `df["Pollutant"]` 的每个元素进行比较,结果是一个布尔 Series。如果长度匹配,DataFrame 将根据布尔值选择行。事实上,我们可以使用按位运算符组合布尔值。例如,这是选择公路车辆产生的一氧化碳排放行的代码:

如果您更喜欢像 Python 列表一样选择行,您可以通过 `iloc` 接口来实现。这是选择第 5 行到第 10 行(从零开始索引)或第 1 列到第 6 列和第 5 行到第 10 行的方法。

如果你熟悉 Excel,你可能知道它一个很棒的功能,叫做“数据透视表”。Pandas 也可以实现同样的功能。我们来考虑一下这个数据集中所有州在 2021 年的的一氧化碳污染情况。

通过数据透视表,我们可以将不同的产生一氧化碳的方式作为列,将不同的州作为行。

上面的 `pivot_table()` 函数不需要将值与索引和列唯一对应。换句话说,如果原始 DataFrame 中一个州有两个“野火”行,这个函数会将这两个聚合(默认取平均值)。要撤销数据透视操作,我们可以使用 `melt()` 函数。

DataFrame 还有更多可以做的事情。例如,我们可以对行进行排序(使用 `sort_values()` 函数),重命名列(使用 `rename()` 函数),删除重复行(`drop_duplicates()` 函数)等等。

在机器学习项目中,我们经常需要在开始使用数据之前进行一些清理工作。Pandas 在这方面非常有用。我们刚刚创建的 `df_pivot` DataFrame 中有一些值为 `NaN`,表示没有可用数据。我们可以用以下任何一种方法将所有这些值替换为零:

DataFrame 中的聚合

事实上,Pandas 提供的表操作功能,否则只能轻松地使用数据库 SQL 语句来完成。重用上面的示例数据集,表中的每种污染物都被分解为不同的来源。如果我们想知道汇总的污染物排放量,我们可以将所有来源加起来。这与 SQL 类似,这是一个“分组”操作。我们可以通过以下方式实现:

`groupby()` 函数的结果将使用分组列作为行索引。它通过将具有相同分组列值的行放入一个组中来工作。然后,作为一个组,将应用一些**聚合**函数,将许多行减少为一行。在上面的例子中,我们是对每一列进行求和。Pandas 提供了许多其他聚合函数,例如计算平均值或仅仅计算行数。由于我们执行的是 `sum()` 操作,非数字列将被从输出中删除,因为它们不适用于该操作。

这使我们能够完成一些有趣的任务。假设,使用上面 DataFrame 中的数据,我们创建一个表格,显示每个州在一氧化碳(CO)和二氧化硫(SO2)的总排放量。其推理过程如下:

  1. 按“State”和“Pollutant”分组,然后对每个组进行求和。这样我们就可以得到每个州每种污染物的总排放量。
  2. 仅选择 2021 年的列。
  3. 运行数据透视表,将州作为行,污染物作为列,总排放量作为值。
  4. 仅选择 CO 和 SO2 的列。

用代码表示就是:

在上面的代码中,`groupby()` 函数之后的每个步骤都是创建一个新的 DataFrame。由于我们使用的是 DataFrame 下定义的函数,因此我们使用了上面的函数式**链式调用语法**。

`sum()` 函数将从 `GroupBy` 对象创建一个 DataFrame,该对象将分组列“State”和“Pollutant”作为索引。因此,在我们将 DataFrame 截断为只有一列后,我们使用 `reset_index()` 将索引转换为列(即会有三列:`State`、`Pollutant` 和 `emissions21`)。由于会有比我们需要的更多的污染物,因此我们使用 `filter()` 从结果 DataFrame 中仅选择 CO 和 SO2 的列。这类似于使用复杂的索引来选择列。

实际上,我们可以用不同的方式做到这一点:

  1. 仅选择 CO 的行并计算总排放量;仅选择 2021 年的数据。
  2. 对 SO2 做同样的事情。
  3. 合并前两步产生的 DataFrame。

在 Pandas 中,DataFrame 有一个 `join()` 函数,可以帮助我们通过匹配索引来合并列与另一个 DataFrame。在代码中,上述步骤如下:

`join()` 函数仅限于索引匹配。如果你熟悉 SQL,Pandas 中 `JOIN` 子句的等价物是 `merge()` 函数。如果为 CO 和 SO2 创建的两个 DataFrame 中,州的列是单独的列,我们可以这样做:

Pandas 中的 `merge()` 函数可以执行所有类型的 SQL 连接。我们可以匹配来自不同 DataFrame 的不同列,并且可以执行左连接、右连接、内连接和外连接。这在整理项目数据时将非常有用。

DataFrame 中的 `groupby()` 函数非常强大,因为它允许我们灵活地操作 DataFrame,并为许多复杂的转换打开了大门。有时在 `groupby()` 之后可能没有内置函数可以提供帮助,但我们总是可以提供自己的函数。例如,这里是创建一个函数来操作子 DataFrame(除了分组列之外的所有列),并应用它来查找最小和最大排放量的年份:

`apply()` 函数是提供最大灵活性的最后手段。除了 GroupBy 对象之外,DataFrame 和 Series 也有 `apply()` 接口。

以下是演示我们上面介绍的所有操作的完整代码:

在 Pandas 中处理时间序列数据

如果你处理时间序列数据,你会发现 Pandas 的另一个强大功能。首先,让我们考虑一些每日污染数据。我们可以从 EPA 的网站选择并下载一些数据。

为说明起见,我们下载了德克萨斯州 2021 年的 PM2.5 数据。我们可以像下面这样导入下载的 CSV 文件,即 ad_viz_plotval_data.csv

pandas 中的 read_csv() 函数允许我们指定某些列为日期,并将它们解析为 datetime 对象而不是字符串。这对于进一步处理时间序列数据至关重要。如我们所知,第一列(零索引)是日期列;我们在上面提供了参数 parse_dates=[0]

为了处理时间序列数据,重要的是在 DataFrame 中使用时间作为索引。我们可以通过 set_index() 函数将其中一列设为索引。

如果我们检查此 DataFrame 的索引,我们会看到以下内容:

我们知道它的类型是 datetime64,这是 pandas 中的一个时间戳对象。

从上面的索引可以看出,每个日期不是唯一的。这是因为 PM2.5 浓度是在不同站点观测的,每个站点都会为 DataFrame 贡献一行。我们可以将 DataFrame 过滤到一个站点,以使索引唯一。或者,我们可以使用 pivot_table() 来转换 DataFrame,其中透视操作保证了生成的 DataFrame 将具有唯一的索引。

我们可以用以下方式检查唯一性:

现在,此 DataFrame 中的每一列都是一个**时间序列**。虽然 pandas 不提供时间序列的任何预测功能,但它提供了可以帮助您清理和转换数据的工具。将 DataFrame 设置为 DateTimeIndex 对于时间序列分析项目非常有用,因为我们可以轻松地提取某个时间间隔的数据,例如时间序列的训练-测试拆分。下面是如何从上面的 DataFrame 中提取三个月的数据子集。

时间序列中一个常用的函数是**重采样**数据。考虑到此 DataFrame 中的每日数据,我们可以将其转换为每周观测值。我们可以指定结果数据按每周日索引。但我们仍然需要告诉重采样数据应该是什么样的。如果是销售数据,我们可能想在整个星期内求和以获得每周收入。在这种情况下,我们可以对一周的数据求平均值以平滑波动。另一种方法是取每个期间的第一次观测值,如下所示:

字符串“W-SUN”用于确定每周日的平均值。这被称为“偏移别名”。您可以在下方找到所有偏移别名的列表:

重采样在金融市场数据中特别有用。设想我们有市场价格数据,但原始数据不是以固定间隔生成的。我们仍然可以使用重采样将数据转换为固定间隔。由于它非常常用,pandas 甚至提供了开-高-低-收(即 OHLC,即一个期间内的第一次、最大值、最小值和最后一次观测值)。下面我们演示如何在一个观测站点上获得每周的 OHLC。

特别地,如果我们从较粗的频率重采样到较细的频率,这被称为**升采样**。Pandas 在升采样期间通常会插入 NaN 值,因为原始时间序列在中间时间实例期间没有数据。一种避免在升采样期间出现这些 NaN 值的方法是要求 pandas 进行前向填充(将值从较早的时间传递)或后向填充(使用较晚时间的值)数据。例如,以下是将一个站点每日 PM2.5 观测值前向填充到每小时。

除了重采样,我们还可以使用滑动窗口来转换数据。例如,下面是如何从时间序列中计算 10 天的移动平均值。这不是重采样,因为生成的数据仍然是每日的。但对于每个数据点,它是过去 10 天的平均值。同样,我们可以通过将不同的函数应用于 rolling 对象来找到 10 天的标准差或 10 天的最大值。

为了展示原始时间序列和滚动平均时间序列的差异,下面是图示。我们在 rolling() 函数中添加了 min_periods=5 参数,因为原始数据在某些天存在缺失数据。这会在每日数据中产生间隙,但我们要求在过去 10 天的窗口中有 5 个数据点时仍然计算平均值。

以下是展示我们上面介绍的时间序列操作的完整代码:

进一步阅读

Pandas 是一个功能丰富的库,其细节远超我们在此介绍的范畴。以下是一些供您深入学习的资源:

API 文档

书籍

总结

在本教程中,您简要了解了 pandas 提供的功能。

具体来说,你学到了:

  • 如何使用 pandas DataFrame 和 Series
  • 如何以类似于关系数据库中的表操作的方式来操作 DataFrame
  • 如何利用 pandas 来帮助操作时间序列数据

掌握机器学习 Python!

Python For Machine Learning

更自信地用 Python 编写代码

...从学习实用的 Python 技巧开始

在我的新电子书中探索如何实现
用于机器学习的 Python

它提供自学教程数百个可运行的代码,为您提供包括以下技能:
调试性能分析鸭子类型装饰器部署等等...

向您展示高级 Python 工具箱,用于
您的项目


查看内容

暂无评论。

留下回复

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。