像字典一样,DataFrame 的索引由哈希表支持。查找行
基于索引值就像根据键查找 dict 值。
相比之下,列中的值类似于列表中的值。
根据索引值查找行比根据列值查找行要快。
例如,考虑
df = pd.DataFrame({'foo':np.random.random(), 'index':range(10000)})
df_with_index = df.set_index(['index'])
以下是查找df['index'] 列等于999 的任何行的方法。
Pandas 必须遍历列中的每个值才能找到等于 999 的值。
df[df['index'] == 999]
# foo index
# 999 0.375489 999
以下是查找索引等于 999 的任何行的方法。通过索引,Pandas 使用哈希值来查找行:
df_with_index.loc[999]
# foo 0.375489
# index 999.000000
# Name: 999, dtype: float64
按索引查找行比按列值查找行快得多:
In [254]: %timeit df[df['index'] == 999]
1000 loops, best of 3: 368 µs per loop
In [255]: %timeit df_with_index.loc[999]
10000 loops, best of 3: 57.7 µs per loop
但是请注意,构建索引需要时间:
In [220]: %timeit df.set_index(['index'])
1000 loops, best of 3: 330 µs per loop
所以只有当你有很多这种类型的查找时,拥有索引才是有利的
执行。
有时索引会在重塑 DataFrame 中发挥作用。很多功能,如set_index、stack、unstack、pivot、pivot_table、melt、
lreshape 和 crosstab,都使用或操作索引。
有时我们希望 DataFrame 具有不同的形状以用于演示目的,或者用于 join、merge 或 groupby 操作。 (正如您所注意到的,也可以基于列值进行连接,但基于索引的连接速度更快。)在幕后,join、merge 和 groupby 尽可能利用快速索引查找。
时间序列有 resample、asfreq 和 interpolate 方法,它们的底层实现也利用了快速索引查找。
所以最后,我认为索引有用的起源,为什么它出现在这么多函数中,是因为它能够执行快速哈希
查找。