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

时间:2014-06-30 17:30:58

标签: 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'])

看起来像这样:

           area  count
co tp
DE Lake      10      7
   Forest    20      5
FR Lake      30      2
   Forest    40      3

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

完成
df.index.levels[0]  # returns ['DE', 'FR]
df.index.levels[1]  # returns ['Lake', 'Forest']

真正喜欢做什么,就是通过按名称解析级别来检索这些列表,即'co''tp' 。我找到的最短的两种方式看起来像这样:

list(set(df.index.get_level_values('co')))  # returns ['DE', 'FR']
df.index.levels[df.index.names.index('co')]  # returns ['DE', 'FR']

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

5 个答案:

答案 0 :(得分:46)

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

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

答案 1 :(得分:23)

Pandas 0.23.0最终introduced解决了这个问题:level的{​​{1}}参数:

Index.unique()

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

答案 2 :(得分:5)

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

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

答案 3 :(得分:2)

如果您要重复进行级别查找,则可以创建索引级别名称的映射,以使用以下内容对唯一值进行级别设置:

df_level_value_map = {
    name: level 
    for name, level in zip(df.index.names, df.index.levels)
}
df_level_value_map['']

但如果您只进行一次此次查询,那么这比原始尝试更有效(或更短)。

我真的希望索引上有一个方法可以返回这样一个字典(或系列?),其名称如下:

df.index.get_level_map(levels={...})

其中levels参数可以将地图限制为现有级别的子集。如果它可能是一个属性,我可以没有参数:

df.index.level_map

答案 4 :(得分:-1)

如果您已经知道索引名称,那么简单地做就不容易了: df['co'].unique()吗?