Pandas:按标签获取唯一的MultiIndex级别值

ojd*_*jdo 52 python pandas

假设你有这个MultiIndex-ed DataFrame:

df = pd.DataFrame({'co':['DE','DE','FR','FR'],
                   'tp':['Lake','Forest','Lake','Forest'],
                   'area':[10,20,30,40],
                   'count':[7,5,2,3]})
df = df.set_index(['co','tp'])
Run Code Online (Sandbox Code Playgroud)

看起来像这样:

           area  count
co tp
DE Lake      10      7
   Forest    20      5
FR Lake      30      2
   Forest    40      3
Run Code Online (Sandbox Code Playgroud)

我想检索每个索引级别的唯一值.这可以使用

df.index.levels[0]  # returns ['DE', 'FR]
df.index.levels[1]  # returns ['Lake', 'Forest']
Run Code Online (Sandbox Code Playgroud)

真正想做的是通过按名称解决这些级别来检索这些列表,即'co''tp'.我找到的最短的两种方式看起来像这样:

list(set(df.index.get_level_values('co')))  # returns ['DE', 'FR']
df.index.levels[df.index.names.index('co')]  # returns ['DE', 'FR']
Run Code Online (Sandbox Code Playgroud)

但非他们非常优雅.有更短的方式吗?

Hap*_*001 47

我想你想要一个多索引的特定级别(和级别名称)的唯一值.我通常会做以下事情,这有点长.

In [11]: df.index.get_level_values('co').unique()
Out[11]: array(['DE', 'FR'], dtype=object)
Run Code Online (Sandbox Code Playgroud)

  • @Robert Muil - 问题在于,如果删除了任何行或列,index.levels不会返回更新的内容,这不会被视为错误,因为这不是MultiIndexes的批准使用(https://github.com/ pydata /熊猫/问题/ 3686).MultiIndex的*current*内容的有效API访问确实是get_level_values.对于那些习惯单独索引唯一性的人来说,这很棘手. (12认同)
  • 但这是非常低效的,因为这个唯一性信息已经明确地存储在索引中,所以你的第二个选项@ojdo在我看来仍然是最好的.使用`unique`对我的数据来说要慢几百倍:`timeit df.index.get_level_values(level ='co').unique()`给出:1000循环,最好是3:**851**每循环μs,而`timeit df.index.levels [df.index.names.index('co')]`给出:100000循环,最佳3:每循环**3.08**μs (4认同)

Pie*_*ton 35

Pandas 0.23.0终于为这个问题引入了一个更清晰的解决方案:level争论Index.unique():

In [3]: df.index.unique(level='co')
Out[3]: Index(['DE', 'FR'], dtype='object', name='co')
Run Code Online (Sandbox Code Playgroud)

现在这是推荐的解决方案.它效率更高,因为它避免在内存中创建级别值的完整表示,并重新扫描它.


Han*_*art 5

另一种方法是通过调用df.index.levels[level_index]可以从中推断出level_index 来查找级别数df.index.names.index(level_name).在上面的示例中,level_name ='co'.

@ Happy001提出的答案计算了可能是计算密集型的唯一性.