代码之家  ›  专栏  ›  技术社区  ›  rahlf23

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

  •  1
  • rahlf23  · 技术社区  · 6 年前

    我最初问过这个问题 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 大于 5 为了这个 索引。因此,如果不符合此标准(即列 小于或等于 5 1 在里面 级别=2 ),然后是相应的 索引将从数据帧中删除。如果全部 指数不符合给定的标准 level=0 索引,然后 索引也将被删除。我上一篇文章包含了我期望的结果(我可以在这里添加它,但为了清晰起见,我希望这篇文章尽可能简洁)。

    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])
    

    这确实产生了我想要的输出,但是对于一个有100000行的数据帧来说,性能相当差。有什么明显的东西我在这里错过了更好地利用引擎盖下的优化 pandas ?

    1 回复  |  直到 6 年前
        1
  •  1
  •   gyx-hh    6 年前

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

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

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