我最初曾问过这个问题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])
的后台优化吗?
答案 0 :(得分:1)
通过执行以下操作,我得到了与您的示例解决方案相同的结果:
df.loc[df.xs('1', level=2)['Val2'] > 5]
与时间性能相比,这要快15倍(在我的机器中,您的示例花费36毫秒,而花费2毫秒)。