内部结构#
本节将介绍 pandas 的一些内部结构。它主要面向 pandas 本身的开发者。
索引#
在 pandas 中,有几个已实现的、可用作轴标签的有效容器对象
Index
:通用的“有序集合”对象,一个内容不作任何假设的对象 dtype 的 ndarray。标签必须是可哈希(且可能不可变)和唯一的。在 Cython 中填充一个从标签到位置的字典,以实现O(1)
查找。MultiIndex
:标准的分层索引对象DatetimeIndex
:一个包含Timestamp
装箱元素的 Index 对象(实现是 int64 值)TimedeltaIndex
:一个包含Timedelta
装箱元素的 Index 对象(实现是 int64 值)PeriodIndex
:一个包含 Period 元素的 Index 对象
有一些函数可以轻松创建常规索引
date_range()
:从时间规则或 DateOffset 生成的固定频率日期范围。一个 Python datetime 对象的 ndarrayperiod_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'])
你可能已经猜到,代码决定了索引的每一层中哪个唯一元素与该位置相关联。重要的是要注意,排序完全由整数代码决定,并且不检查(或关心)层级本身是否已排序。幸运的是,构造函数 from_tuples()
和 from_arrays()
确保了这一点,但如果你自己计算层级和代码,请务必小心。
值#
pandas 使用自定义类型(如 Categorical
或带时区的时间戳)扩展了 NumPy 的类型系统,因此我们有多种“值”的概念。对于一维容器(Index
类和 Series
),我们遵循以下约定
cls._values
指的是“最佳可能”数组。这可能是一个ndarray
或ExtensionArray
。
因此,例如,Series[category]._values
是一个 Categorical
。
子类化 pandas 数据结构#
本节已移至子类化 pandas 数据结构。