如果子索引的列值符合条件,则从MultiIndex数据框中删除索引

时间:2018-09-20 03:48:33

标签: python pandas pandas-groupby multi-index

我最初曾问过这个问题here,但我认为它被错误地标记为重复项。我将尽力在这里澄清我的问题以及我如何认为它是独一无二的。

给出以下示例MultiIndex数据框:

import pandas as pd
import numpy as np

first = ['A', 'B', 'C']
second = ['a', 'b', 'c', 'd']
third = ['1', '2', '3']

indices = [first, second, third]

index = pd.MultiIndex.from_product(indices, names=['first', 'second', 'third'])

df = pd.DataFrame(np.random.randint(10, size=(len(first)*len(second)*len(third), 4)), index=index, columns=['Val1','Val2',' Val3', 'Val4'])

目标:如果列level=1的值对应于索引值{{,我想保留一个特定的'a'索引(例如'Val2')对于该1索引,level=2中的1}}大于5。因此,如果不满足此条件(即level=1中索引'Val2'的列5小于或等于1),则对应的level=2索引将从数据框中删除。如果所有level=1索引均不满足给定level=1索引的条件,则该level=0索引也将被删除。我的前一篇文章包含了我的预期输出(我可以在此处添加,但为了清晰起见,我希望这篇文章尽可能简洁)。

这是我当前的解决方案,我相信它的性能可以提高:

level=0

这确实产生了我想要的输出,但是对于具有100,000行的数据帧,性能相当差。有什么明显的我想念的地方,可以更好地利用grouped = df.groupby(level=0) output = pd.concat([grouped.get_group(key).groupby(level=1).filter(lambda x: (x.loc[pd.IndexSlice[:, :, '1'], 'Val2']>5).any()) for key, group in grouped]) 的后台优化吗?

1 个答案:

答案 0 :(得分:1)

通过执行以下操作,我得到了与您的示例解决方案相同的结果:

df.loc[df.xs('1', level=2)['Val2'] > 5]

与时间性能相比,这要快15倍(在我的机器中,您的示例花费36毫秒,而花费2毫秒)。