路线图
本页概述了 pandas 开发的主要主题。其中每一项都需要付出相对较大的努力来实施。如果有专门的资金或贡献者的兴趣,这些可以更快地实现。
路线图上的项目并不意味着它一定会 发生,即使有无限的资金。在实施期间,我们可能会发现阻碍该功能采用的问题。
此外,路线图上没有的项目并不排除它包含在 pandas 中。该路线图旨在对项目进行更大规模、根本性的更改,这些更改可能需要开发人员数月或数年的时间。我们的问题跟踪器将继续跟踪较小范围的项目。
该路线图被定义为一组名为 PDEP 的主要增强提案。有关 PDEP 以及如何提交 PDEP 的更多信息,请参阅 PEDP-1。
PDEP
正在讨论中
- PDEP-1 修订(决策)
- PDEP-8:pandas 中的就地方法
- PDEP-11:将 dropna 的默认值更改为 False
- PDEP-13:弃用 Series 和 DataFrame 上的 apply 方法,并使 agg 和 transform 方法对系列数据进行操作
公认
- PDEP-1:目的和指南
- PDEP-6:禁止在类似 setitem 的操作中进行向上转换
- PDEP-7:使用 Copy-on-Write 在 pandas 中实现一致的复制/查看语义
- PDEP-10:PyArrow 作为默认字符串推理实现所需的依赖项
实施的
拒绝
等待 PDEP 的路线图要点
可扩展性
Pandasextending.extension-types
允许使用自定义数据类型和数组存储来扩展 NumPy 类型。Pandas 在内部使用扩展类型,并为第三方库提供接口来定义自己的自定义数据类型。
pandas 的许多部分仍然会无意中将数据转换为 NumPy 数组。这些问题对于嵌套数据尤其明显。
我们希望改进整个库中扩展数组的处理,使它们的行为与 NumPy 数组的处理更加一致。我们将通过清理 pandas 的内部结构并向扩展数组接口添加新方法来实现这一点。
字符串数据类型
目前,pandas 将文本数据存储在object
-dtype NumPy 数组中。当前的实现有两个主要缺点:首先,object
-dtype 不是特定于字符串的:任何 Python 对象都可以存储在
object
-dtype 数组中,而不仅仅是字符串。第二:这效率不高。NumPy 内存模型并不是特别适合可变宽度文本数据。
为了解决第一个问题,我们提出了一种新的字符串数据扩展类型。这最初将是选择加入的,用户明确请求
dtype="string"
。支持此字符串 dtype 的数组最初可能是当前实现:object
Python 字符串的 -dtype NumPy 数组。
为了解决第二个问题(性能),我们将探索替代内存数组库(例如 Apache Arrow)。作为工作的一部分,我们可能需要实现 pandas 用户期望的某些操作(例如,中使用的算法Series.str.upper
)。这项工作可以在 pandas 之外完成。
Apache Arrow 互操作性
Apache Arrow是一个针对内存数据的跨语言开发平台。Arrow 逻辑类型与典型的 pandas 用例密切相关。
我们希望为 pandas 中的 Arrow 内存和数据类型提供更好的集成支持。这将使我们能够利用其 I/O 功能,并使用 Arrow 提供与其他语言和库更好的互操作性。
块管理器重写
我们想用更简单的一维数组集合替换 pandas 当前的内部数据结构(一维或二维数组的集合)。
Pandas 的内部数据模型相当复杂。DataFrame 由一个或多个二维“块”组成,每个数据类型有一个或多个块。这个二维数组的集合由 BlockManager 管理。
BlockManager 的主要好处是提高了某些操作的性能(从 2D 数组构建、二进制操作、跨列缩减),特别是对于宽 DataFrame。然而,BlockManager 大大增加了 pandas 的复杂性和维护负担。
通过替换BlockManager我们希望实现
- 代码明显更简单
- 新逻辑类型更容易扩展
- 用户更好地控制内存使用和布局
- 改善微观性能
- 向 pandas 内部提供 C/Cython API 的选项
有关更多信息,请参阅这些设计文档。
索引和内部结构的解耦
在 pandas 数据结构中获取和设置值的代码需要重构。特别是,我们必须清楚地将将键(例如 的参数DataFrame.loc
)转换为位置的代码与使用这些位置获取或设置值的代码分开。这与提议的 BlockManager 重写有关。目前,BlockManager 有时使用基于标签的索引,而不是基于位置的索引。我们建议它只适用于位置索引,并且键到位置的转换应该完全在更高的级别上完成。
索引是一个复杂的 API,有很多微妙之处。这种重构需要小心和注意。以下原则应该激发索引代码的重构,并应该产生更干净、更简单、性能更高的代码。
-
标签索引绝不能涉及在轴中查找相同标签两次。这意味着任何验证步骤都必须:
-
将验证限制为一般功能(例如键/索引的数据类型/结构),或者
-
将结果重新用于实际索引。
-
索引器绝不能依赖于对其他索引器的显式调用。例如,可以有一些内部方法调用(或其公共基类)
.loc
的某些内部方法,但决不应该出现在代码流中。__getitem__
.loc
the_obj[something]
-
位置索引的执行绝不能涉及标签(不幸的是,目前正在发生这种情况)。也就是说,getter 调用(或右侧未索引的 setter 调用)的代码流决不应该以
.iloc
任何方式涉及对象的轴。 -
索引绝不能多次涉及访问/修改值(即作用于
._data
或)。.values
因此,以下步骤必须明确分离: -
找到我们需要在每个轴上访问/修改的位置
- (如果我们正在访问)导出我们需要返回的对象的类型(维度)
- 实际访问/修改值
-
(如果我们正在访问)构造返回对象
-
作为 4.i 和 4.iii 之间解耦的必然结果,任何涉及数据存储方式的代码(包括处理多个数据类型、稀疏存储、分类、第三方类型的任意组合)都必须独立于以下代码:处理识别受影响的行/列,并且仅在步骤 4.i 完成后才会发生。
-
特别是,这样的代码很可能不应该存在于
pandas/core/indexing.py
-
...并且不得以任何方式依赖于轴的类型(例如没有
MultiIndex
特殊情况) -
作为第 1.i 点的推论,
Index
(子)类必须为任何所需的标签有效性检查(一方面不涉及实际查找)以及任何所需的标签转换/适应/查找提供单独的方法(s),另一方面。 -
尝试和错误的使用应该受到限制,并且无论如何仅限于捕获实际预期的异常(通常是
KeyError
)。 -
特别是,代码永远不应该(故意)在
except
a 的部分引发新的异常。try... exception
-
任何非特定于 setter 和 getter 的代码部分都必须共享,并且当预期行为存在微小差异时(例如,因
.loc
缺少标签而引发提升,而设置仍然不会),可以使用特定参数来管理它们。
Numba 加速操作
Numba是 Python 代码的 JIT 编译器。我们希望为用户提供应用自己的 Numba-jitted 函数的方法,其中 pandas 接受用户定义的函数(例如,
在 groupby 和窗口上下文中的Series.apply
、
DataFrame.apply
、
DataFrame.applymap
和 )。这将通过保留在编译的代码中来提高这些操作中用户定义函数的性能。
文档改进
我们希望改进 pandas 文档的内容、结构和表示方式。一些具体目标包括
- 采用现代的响应式设计彻底改造 HTML 主题 (
15556
) - 完善“入门”文档,为不同背景的用户设计和编写学习路径(例如全新编程、熟悉R等其他语言、已经熟悉Python)。
- 改进文档的整体组织和文档的特定小节,使导航和查找内容更加容易。
性能监控
Pandas 使用空速 来监控性能回归。ASV 本身是一个很棒的工具,但需要一些额外的工作才能集成到开源项目的工作流程中。
asv -runner组织目前由 pandas 维护者组成,提供基于 ASV 构建的工具。我们有一台用于运行多个项目基准测试的物理机器,以及管理基准测试运行和报告结果的工具。
我们愿意资助这些工具的改进和维护
- 更加稳定。目前,它们是在维护人员有空闲时间的晚上和周末进行维护的。
- 按照https://pyperf.readthedocs.io/en/latest/system.html调整系统基准以提高稳定性
- 构建一个 GitHub 机器人以在合并 PR之前请求 ASV 运行。目前,基准测试仅在夜间运行。