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

索引数据帧,其中(多)索引仅包含数据帧的某些级别

  •  0
  • BallpointBen  · 技术社区  · 8 年前

    我希望获取一个具有多索引的数据帧,并使用另一个(多)索引对其进行索引,该索引包含数据帧级别的严格子集。数据帧中不在其他(多)索引中的级别应返回所有行。例如:

    >>> df
                  col
    num chr
    1   a    0.845402
        b    0.099432
        c    0.507409
    2   a    0.684363
        b    0.582436
        c    0.666528
    
    >>> df['col'].unstack('chr').mean()
    chr
    a    0.764883
    b    0.340934
    c    0.586968
    dtype: float64
    
    >>> df['col'].unstack('chr').mean().nsmallest(2)
    chr
    b    0.340934
    c    0.586968
    dtype: float64
    
    >>> df['col'].unstack('chr').mean().nsmallest(2).index
    Index(['b', 'c'], dtype='object', name='chr')
    

    现在,我想返回 df 包含 'b' 或 'c' 在 'chr' 级别,以及 'num' 数量此外,我还想尝试同样的方法,在最后一步中返回的索引是 MultiIndex (即,何时 df公司 的索引有两个以上级别):

    >>> df
                      col
    num chr foo
    1   a   bar  0.790995
            baz  0.883363
        b   bar  0.240376
            baz  0.309544
        c   bar  0.637943
            baz  0.265628
    2   a   bar  0.783172
            baz  0.612230
        b   bar  0.729979
            baz  0.846814
        c   bar  0.809676
            baz  0.821503
    
    >>> df['col'].unstack(['chr', 'foo']).mean()
    chr  foo
    a    bar    0.787084
         baz    0.747796
    b    bar    0.485177
         baz    0.578179
    c    bar    0.723809
         baz    0.543565
    dtype: float64
    
    >>> df['col'].unstack(['chr', 'foo']).mean().nsmallest(2)
    chr  foo
    b    bar    0.485177
    c    baz    0.543565
    dtype: float64
    
    >>> df['col'].unstack(['chr', 'foo']).mean().nsmallest(2).index
    MultiIndex(levels=[['a', 'b', 'c'], ['bar', 'baz']],
               labels=[[1, 2], [0, 1]],
               names=['chr', 'foo'])
    

    我想选择所有行 df公司 其索引包含 ('b', 'bar') 或 ('c', 'baz') 在最后两个级别和 '数字' 数量

    2 回复  |  直到 8 年前
        1
  •  0
  •   BENY    8 年前

    我只能用 get_level_values 和 isin

    s=df['col'].mean(level=[1,2]).nsmallest(2).index.tolist()
    
    df[pd.Series(list(zip(df.index.get_level_values(1),df.index.get_level_values(2)))).isin(s).values]
    Out[163]:
                      col
    num chr foo
    1   b   bar  0.240376
        c   baz  0.265628
    2   b   bar  0.729979
        c   baz  0.821503
    
        2
  •  0
  •   BallpointBen    8 年前

    我认为最干净的解决方案可能是分别检索所需的行 pd.concat 他们对于 Index 解决方案:

    idx = df['col'].unstack(['chr', 'foo']).mean().nsmallest(2).index
    selected = pd.concat([df.xs(label, level=idx.name, drop_level=False) 
                          for label in idx],
                         axis=0)
    

    什么时候 idx 是一个 MultiIndex 使用 level=idx.names 相反