多列的pandas get_level_values

dan*_*dar 10 python multi-index dataframe python-3.x pandas

有没有一种方法可以获取get_level_values不止一列的结果?

给定以下内容DataFrame

         d
a b c     
1 4 10  16
    11  17
  5 12  18
2 5 13  19
  6 14  20
3 7 15  21
Run Code Online (Sandbox Code Playgroud)

我希望得到的值(水平的元组的列表)ac

[(1, 10), (1, 11), (1, 12), (2, 13), (2, 14), (3, 15)]
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 不能给出get_level_values一个以上的等级(例如 df.index.get_level_values(['a','c']

  • 有一种解决方法,可以get_level_values在每个所需的列上同时使用zip它们:

例如:

a_list = df.index.get_level_values('a').values
c_list = df.index.get_level_values('c').values

print([i for i in zip(a_list,c_list)])
[(1, 10), (1, 11), (1, 12), (2, 13), (2, 14), (3, 15)]
Run Code Online (Sandbox Code Playgroud)

但是随着列数的增加,它变得很麻烦。

  • 构建示例的代码DataFrame

df = pd.DataFrame({'a':[1,1,1,2,2,3],'b':[4,4,5,5,6,7,],'c':[10,11,12,13,14,15], 'd':[16,17,18,19,20,21]}).set_index(['a','b','c'])

Alb*_*oso 6

.tolist()方法MultiIndex给出了中所有级别的元组列表MultiIndex。举例来说DataFrame

df.index.tolist()
# => [(1, 4, 10), (1, 4, 11), (1, 5, 12), (2, 5, 13), (2, 6, 14), (3, 7, 15)]
Run Code Online (Sandbox Code Playgroud)

因此,这里有两个想法:

  1. 从原始的获取元组列表MultiIndex并过滤结果。

    [(a, c) for a, b, c in df.index.tolist()]
    # => [(1, 10), (1, 11), (1, 12), (2, 13), (2, 14), (3, 15)]
    
    Run Code Online (Sandbox Code Playgroud)

    这种简单方法的缺点是您需要手动指定所需级别的顺序。您可以利用itertools.compress名称来选择它们。

    from itertools import compress
    
    mask = [1 if name in ['a', 'c'] else 0 for name in df.index.names]
    [tuple(compress(t, mask)) for t in df.index.tolist()]
    # => [(1, 10), (1, 11), (1, 12), (2, 13), (2, 14), (3, 15)]
    
    Run Code Online (Sandbox Code Playgroud)
  2. 创建具有所需级别的MultiIndex并对其进行调用.tolist()

    df.index.droplevel('b').tolist()
    # => [(1, 10), (1, 11), (1, 12), (2, 13), (2, 14), (3, 15)]
    
    Run Code Online (Sandbox Code Playgroud)

    如果您想命名要保留的级别(而不是要降低的级别),则可以执行以下操作

    df.index.droplevel([level for level in df.index.names
                    if not level in ['a', 'c']]).tolist()
    # => [(1, 10), (1, 11), (1, 12), (2, 13), (2, 14), (3, 15)]
    
    Run Code Online (Sandbox Code Playgroud)