加快大熊猫多级指数选择的方法



我有一个数据框,并且想每次都为'a', 'b','c'值的特定元组在一个小分区上工作。

df = pd.DataFrame({'a':np.random.randint(0,10,10000),
                   'b':np.random.randint(0,10,10000),
                   'c':np.random.randint(0,10,10000),
                   'value':np.random.randint(0,100,10000)})

所以我选择使用熊猫多索引:

dfi = df.set_index(['a','b','c'])
dfi.sortlevel(inplace = True)

但是,性能不是很好。

%timeit dfi.ix[(2,1,7)] # 511 us
%timeit df[(df['a'].values == 2) & 
           (df['b'].values == 1) & (df['c'].values == 7)] # 247 us

我怀疑某处有一些开销。我的程序有 ~1k 元组,所以一次运行需要 511 * 1000 = 0.5 秒。如何进一步改进?

更新:

嗯,我忘了提到元组的数量小于 df 中不同值'a', 'b','c'的总笛卡尔乘积。groupby不会对我的元组中不存在的索引做多余的工作吗?

不清楚

"工作"是什么意思,但我会这样做

这几乎可以是任何功能

In [33]: %timeit df.groupby(['a','b','c']).apply(lambda x: x.sum())
10 loops, best of 3: 83.6 ms per loop

某些操作被细胞化,因此非常快

In [34]: %timeit df.groupby(['a','b','c']).sum()
100 loops, best of 3: 2.65 ms per loop

对多索引进行选择对于逐个索引执行索引效率不高。

如果你

对整个组的非常小的子集进行操作,那么你可能希望直接索引到多索引中;如果你对一小部分(可能是 20%)或更多的组进行操作,则 groupby 获胜。您可能还需要调查可用于根据某些条件预筛选组filter

如上所述,组索引器的笛卡尔乘积无关紧要。只有实际的组才会被 groupby 迭代(将 MultiIndex 视为总可能空间的稀疏表示)。

怎么样:

dfi = df.set_index(['a','b','c'])
dfi.sortlevel(inplace = True)
value = dfi["value"].values
value[dfi.index.get_loc((2, 1, 7))]

结果是一个没有索引的 ND数组。

最新更新