Skip to content

Files

Latest commit

8db93a3 · Jul 17, 2020

History

History
223 lines (119 loc) · 9.39 KB

File metadata and controls

223 lines (119 loc) · 9.39 KB

五、数据帧的结构操作

Pandas 提供了一个强大的操纵引擎,供您用来浏览数据。 这种探索通常涉及对DataFrame对象的结构进行修改,以删除不必要的数据,更改现有数据的格式或从其他行或列中的数据创建派生数据。 这些章节将演示如何执行这些强大而重要的操作。

具体而言,在本章中,我们将介绍:

  • 重命名列
  • 使用[].insert()添加新列
  • 通过扩展添加列
  • 使用连接添加列
  • 重新排序列
  • 替换列的内容
  • 删除列
  • 添加新行
  • 连接行
  • 通过扩展添加和替换行
  • 使用.drop()删除行
  • 使用布尔选择删除行
  • 使用切片删除行

配置 Pandas

以下代码将为以下示例配置 Pandas 环境。 这还将加载 S&P 500 数据集,以便可以在示例中使用它:

重命名列

可以使用适当命名的.rename()方法重命名列。 可以向此方法传递一个字典对象,其中的键表示要重命名的列的标签,并且每个键的值是新名称。

下面的操作会将'Book Value'列的名称更改为'BookValue',删除空格并允许使用属性符号访问该列的数据。

以这种方式使用.rename()将返回一个新的数据帧,其中的列已重命名,并且数据是从原始数据中复制的。 以下内容验证了原始文件没有被修改。

要在不进行复制的情况下就地修改数据帧,可以使用inplace=True参数。

现在可以使用.BookValue属性访问数据。

使用[].insert()添加新列

可以使用[]运算符将新列添加到数据帧。 让我们添加一个名为RoundedPrice的新列,该列将表示Price列中值的舍入。

Pandas 执行此操作的方式是,首先从sp500中选择Price列的数据,然后将Series中的所有值四舍五入。 然后,pandas 将新的Series与副本DataFrame对齐,并将其添加为名为RoundedPrice的新列。 新列将添加到列索引的末尾。

.insert()方法可用于在特定位置添加新列。 下面在SectorPrice之间插入RoundedPrice列:

通过扩展来添加列

可以使用.loc[]属性和切片添加列。 下面通过向名为PERsp500的子集添加新列,并将所有值初始化为0来演示这一点。

具有现有数据的Series也可以通过这种方式添加。 下面将PER列与随机数据的序列相加。 由于这使用对齐方式,因此有必要使用与目标数据帧相同的索引。

使用连接来添加列

[]运算符和.insert()方法都就地修改目标数据帧。 如果需要一个带有附加列的新数据帧(保持原来的不变),则可以使用pd.concat()函数。 此函数创建一个新的数据帧,其中所有指定的DataFrame对象均按规范顺序连接在一起。

下面的代码创建了一个新的DataFrame,其中的一列包含了四舍五入的价格。 然后,它使用pd.concat()axis=1来表示给定的DataFrame对象应沿着列轴连接(与使用axis=0的行相比)。

在第 11 章(合并,关联和重塑数据)中将更详细地介绍连接。

连接可能会导致重复的列名。 为了演示这种情况,让我们重新创建rounded_price,但将其命名为Price列。

现在,连接将导致重复的列。

有趣的是,您可以使用.Price属性检索这两列。

如果要在场景中获取特定的Price列,则需要按位置而不是名称进行检索。

对列重新排序

通过按所需顺序选择列,可以重新排列列的顺序。 下面通过反转列进行演示。

实际上,没有一种方法可以就地更改列的顺序。 参见这里

替换列的内容

通过使用[]运算符将新的Series分配给现有列,可以替换DataFrame的内容。 以下演示了用rounded_price中的Price列替换Price列。

列的数据也可以使用切片替换(就地)。

删除列

可以使用数据帧的del关键字或.pop().drop()方法从DataFrame中删除列。 这些行为的差异略有不同:

  • del将从DataFrame中删除Series(原地)
  • pop()将同时删除Series并返回Series(也是原地)
  • drop(labels, axis=1)将返回一个已删除列的新数据帧(原始DataFrame对象未修改)

下面演示了如何使用delsp500数据的副本中删除BookValue列:

以下使用.pop()方法删除Sector列:

.pop()方法的优势在于它为我们提供了弹出的列。

.drop()方法可用于删除行和列。 要使用它删除列,请指定axis=1

追加新行

使用DataFrame.append()方法执行行的追加。 附加过程将返回一个新的DataFrame,并首先添加来自原始DataFrame的数据,然后再添加第二行的数据。 追加不会执行对齐,并且可能导致索引标签重复。

以下代码演示了附加两个从sp500数据中提取的DataFrame对象。 第一个DataFrame由行(按位置)012组成,第二个DataFrame由行(按位置)10112组成。 两者中都包含位置2处的行(带有标签ABBV),以演示重复索引标签的创建。

追加中使用的DataFrame对象的列集不必相同。 结果数据帧将由两个列的并集组成,缺少的列数据填充有NaN。 以下内容通过使用与df1相同的索引创建第三个数据帧,但只有一个列的名称不在df1中来说明这一点。

现在,我们附加df3df1

ignore_index=True参数可用于附加,而无需强制从DataFrame保留索引。 当索引值的意义不大并且您只希望将具有顺序递增的整数的级联数据用作索引时,这很有用:

请注意,结果DataFrame具有默认的RangeIndex,并且索引(Symbol))中的数据已从结果中完全排除。

连接行

可以使用pd.concat()函数并通过指定axis=0将来自多个DataFrame对象的行彼此连接。 沿行轴在两个DataFrame对象上进行pd.concat()的默认操作的方式与.append()方法相同。

通过重建前面的附加示例中的两个数据集并将其连接起来,可以证明这一点。

如果所有DataFrame对象中的列集都不相同,则 Pandas 将用NaN填充这些值。

从源对象中逐行复制行会导致重复的索引标签。 keys参数可用于帮助区分一组行源自哪个数据帧。 下面通过使用keys向表示源对象的索引添加一个级别进行演示:

我们将在第 6 章“处理索引”中更详细地研究层次结构索引。

通过扩展来添加和替换行

也可以使用.loc属性将行添加到DataFrame.loc的参数指定要放置行的索引标签。 如果标签不存在,则使用给定的索引标签将值附加到数据帧。 如果标签确实存在,则将替换指定行中的值。

以下示例获取sp500的子集,并添加带有标签FOO的行:

请注意,无论是添加还是替换行,都会进行此更改。

使用.drop()删除行

DataFrame.drop()方法可用于删除行。 .drop()方法获取要删除的索引标签列表,并返回DataFrame的副本,其中删除了指定的行。

使用布尔选择删除行

布尔选择也可以用于从DataFrame中删除行。 布尔选择的结果将返回表达式为 True 的行的副本。 要删除行,只需构造一个表达式,为要删除的行返回False,然后将该表达式应用于数据帧。

下面的示例演示删除Price大于300的行。 首先,构造表达式。

根据此结果,我们现在知道有 10 行的价格大于 300。要获得删除了这些行的数据帧,请选择选择的补码。

使用切片删除行

切片可用于从数据帧中删除记录。 这是一个与布尔选择类似的过程,在该过程中,我们选择了除要删除的行以外的所有行。

假设我们要从sp500中除去除前三个记录以外的所有记录。 执行此任务的片是[:3],它返回前三行。

请记住,由于这是切片,因此结果是原始数据帧的视图。 这些行尚未从sp500数据中删除,对这三行的更改将更改sp500中的数据。 防止这种情况的正确措施是制作切片的副本,这会导致复制指定行的数据的新数据帧。

总结

在本章中,您学习了如何使用 Pandas DataFrame对象执行几种常见的数据操作,特别是通过添加或删除行和列来更改DataFrame结构的操作。 此外,我们看到了如何替换特定行和列中的数据。

在下一章中,我们将更详细地研究索引的使用,以便能够有效地从 pandas 对象内检索数据。