Pandas Index Filter比非索引列过滤器慢

时间:2018-02-07 16:08:09

标签: python pandas optimization indexing

我计时了两次Pandas查询,希望通过索引实现更高的速度。然而,恰恰相反。有人可以解释为什么会这样吗?或者我做的事情是不是错了?我的理解是,Pandas索引作为哈希表工作,并且查找将在恒定时间内发生。就行过滤而言,我认为它是一种顺序过滤,每次应用过滤器时,都会扫描数据帧中的所有行。

数据集大约有800万行和7列。我试图通过字符串值的组合过滤数据不唯一的列。

In [1]: import pandas as pd

In [2]: df = pd.read_csv("/path/to/file", header=None, sep='\t', usecols=[0,1,2,3,5,6,7], names=['A', 'B', 'C', 'D', 'E', 'F', 'G'])

In [3]: %timeit -n10 df[df['B'].isin(['S1', 'S2'])]
10 loops, best of 3: 145 ms per loop

In [4]: df.dtypes
Out[4]: 
A       object
B      object
C      int64
D      int64
E      float64
F      float64
G     object
dtype: object

In [5]: df.shape
Out[5]: (8468828, 7)

索引后:

In [4]: df2 = pd.read_csv("/path/to/file", header=None, sep='\t', usecols=[0,1,2,3,5,6,7], names=['A', 'B', 'C', 'D', 'E', 'F', 'G'])

In [5]: df2.set_index('B', inplace=True)

In [6]: %timeit -n10 df2.loc[['S1', 'S2']]
10 loops, best of 3: 302 ms per loop

2 个答案:

答案 0 :(得分:2)

.loc在Python中实现,因此速度很慢。

第一种方式有两件事:

  1. 计算.isin。这是您的代码所采用的a link to the path。它依赖于hashtable模块,该模块是用cython编写的(并以接近c速度运行)。
  2. 一旦你计算了一个面具,应用它大部分是用numpy完成的,这再次意味着c速度。
  3. 故事的寓意是坚持c / cython土地比在Python土地上工作更快。

答案 1 :(得分:1)

关于如何在pandas中处理索引的

@HYRY's explanation是有用的信息:

  

当index是唯一的时,pandas使用哈希表将键映射到值O(1)。   当索引是非唯一且已排序时,pandas使用二进制搜索O(log N ),   当索引是随机排序时,pandas需要检查所有的密钥   index O( N )。