重复标签#

Index 对象不一定唯一;您可以 having 重复的行或列标签。这乍一看可能有点令人困惑。如果您熟悉 SQL,您就知道行标签类似于表的主键,并且您永远不希望 SQL 表中有重复项。但是 pandas 的作用之一是在将凌乱的、真实世界的数据馈送到某个下游系统之前对其进行清理。真实世界的数据包含重复项,即使在应该唯一的地方也是如此。

本节描述了重复标签如何改变某些操作的行为,以及如何在操作过程中防止重复项的产生,或者在它们出现时检测到它们。

重复标签的后果#

一些 pandas 方法(例如 Series.reindex() )在存在重复项时根本无法工作。输出无法确定,因此 pandas 会引发错误。

其他方法,例如索引,可能会产生非常令人惊讶的结果。通常,使用标量进行索引会 降低维度。使用标量切片 DataFrame 将返回一个 Series。使用标量切片 Series 将返回一个标量。但是,有了重复项,情况就不是这样了。

列中存在重复项。如果我们对 'B' 进行切片,我们会得到一个 Series

但是对 'A' 进行切片会返回一个 DataFrame

这同样适用于行标签

重复标签检测#

您可以使用 Index 来检查 Index.is_unique (存储行或列标签)是否唯一:

备注

检查索引是否唯一对于大型数据集来说是一种成本较高操作。pandas 会缓存此结果,因此对同一索引进行重新检查会非常快。

Index.duplicated() 将返回一个布尔 ndarray,指示标签是否重复。

这可以用作布尔过滤器来删除重复行。

如果您需要额外的逻辑来处理重复标签,而不仅仅是删除重复项,那么使用索引上的 groupby() 是一种常用技巧。例如,我们将通过计算具有相同标签的所有行的平均值来解决重复问题。

禁止重复标签#

在 1.2.0 版本加入.

As noted above, handling duplicates is an important feature when reading in raw data. That said, you may want to avoid introducing duplicates as part of a data processing pipeline (from methods like pandas.concat(), rename(), etc.). Both Series and DataFrame disallow duplicate labels by calling .set_flags(allows_duplicate_labels=False). (the default is to allow them). If there are duplicate labels, an exception will be raised.

This applies to both row and column labels for a DataFrame

此属性可以通过 allows_duplicate_labels 来检查或设置,该属性指示该对象是否允许重复标签。

DataFrame.set_flags() 可用于返回一个新的 DataFrame,其中 allows_duplicate_labels 等属性设置为某个值

返回的新 DataFrame 是对旧 DataFrame 相同数据的视图。或者,属性可以直接在同一对象上设置

在处理原始的、混乱的数据时,您可能最初会读取混乱的数据(可能包含重复标签),进行去重,然后禁止后续操作引入重复项,以确保数据管道不会引入重复项。

>>> raw = pd.read_csv("...")
>>> deduplicated = raw.groupby(level=0).first()  # remove duplicates
>>> deduplicated.flags.allows_duplicate_labels = False  # disallow going forward

在具有重复标签的 SeriesDataFrame 上设置 allows_duplicate_labels=False,或者对不允许重复标签的 SeriesDataFrame 执行会引入重复标签的操作,将引发 errors.DuplicateLabelError

此错误消息包含重复的标签,以及 SeriesDataFrame 中所有重复项(包括“原始项”)的数字位置

重复标签传播#

总的来说,禁止重复标签是“粘滞”的。它会在操作过程中得以保留。

警告

这是一个实验性功能。目前,许多方法未能传播 allows_duplicate_labels 值。预计在未来版本中,所有接受或返回一个或多个 DataFrame 或 Series 对象的都会传播 allows_duplicate_labels