假设你有这个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']
但他们中的非常优雅。有更短的方式吗?
答案 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()
吗?