内部机制#

本节将介绍 pandas 的一些内部机制。它主要面向 pandas 的开发者。

索引#

在 pandas 中实现了一些对象,它们可以用作轴标签的有效容器

  • Index: 通用“有序集合”对象,是一个假设对其内容一无所知的对象 dtype 的 ndarray。标签必须是可哈希的(并且很可能是不可变的)且唯一的。在 Cython 中填充一个从标签到位置的字典,以实现 O(1) 查找。

  • MultiIndex: 标准的分层索引对象

  • DatetimeIndex: 包含 Timestamp 装箱元素的 Index 对象(实现是 int64 值)

  • TimedeltaIndex: 包含 Timedelta 装箱元素的 Index 对象(实现是 in64 值)

  • PeriodIndex: 包含 Period 元素的 Index 对象

有一些函数可以轻松创建常规索引

  • date_range(): 从时间规则或 DateOffset 生成的固定频率日期范围。一个包含 Python datetime 对象的 ndarray

  • period_range(): 从时间规则或 DateOffset 生成的固定频率日期范围。一个包含 Period 对象的 ndarray,表示时间跨度

警告

不支持自定义 Index 子类,应改为使用 ExtensionArray 接口实现自定义行为。

MultiIndex#

在内部,MultiIndex 由几部分组成:levels(层级)、整数 codes(编码)和层级 names(名称)

In [1]: index = pd.MultiIndex.from_product(
   ...:     [range(3), ["one", "two"]], names=["first", "second"]
   ...: )
   ...: 

In [2]: index
Out[2]: 
MultiIndex([(0, 'one'),
            (0, 'two'),
            (1, 'one'),
            (1, 'two'),
            (2, 'one'),
            (2, 'two')],
           names=['first', 'second'])

In [3]: index.levels
Out[3]: FrozenList([[0, 1, 2], ['one', 'two']])

In [4]: index.codes
Out[4]: FrozenList([[0, 0, 1, 1, 2, 2], [0, 1, 0, 1, 0, 1]])

In [5]: index.names
Out[5]: FrozenList(['first', 'second'])

您可能可以猜到,codes 决定了索引的每一层中与该位置对应的唯一元素。需要注意的是,排序是由整数 codes 唯一决定的,并且不检查(或不关心)levels 本身是否已排序。幸运的是,构造函数 from_tuples()from_arrays() 确保了这一点,但如果您自己计算 levels 和 codes,请务必小心。

#

pandas 通过自定义类型扩展了 NumPy 的类型系统,例如 Categorical 或带有时区的 datetime,因此我们对“值”有多种概念。对于一维容器(Index 类和 Series),我们有以下约定

  • cls._values 指的是“最佳可能”数组。它可以是一个 ndarrayExtensionArray

因此,例如,Series[category]._values 是一个 Categorical

pandas 数据结构子类化#

本节已移至 pandas 数据结构子类化