在DataFrame中出现的MultiIndex级别的组合

时间:2015-08-13 14:41:09

标签: python pandas

我有一个像这样的MultiIndexed DataFrame:

In [2]: ix = pd.MultiIndex.from_product([[1, 2, 3], ['foo', 'bar'], ['baz', 'can']], names=['a', 'b', 'c'])
In [3]: data = np.arange(len(ix))
In [4]: df = pd.DataFrame(data, index=ix, columns=['hi'])
In [43]: df = df[~df.hi.isin([2, 3])]
In [44]: df
Out[44]: 
           hi
a b   c      
1 foo baz   0
      can   1
2 foo baz   4
      can   5
  bar baz   6
      can   7
3 foo baz   8
      can   9
  bar baz  10
      can  11

我想知道DataFrame中出现ab的哪些级别:

[(1, 'foo'), (2, 'foo'), (2, 'bar'), (3, 'foo'), (3, 'bar')]

我可以使用pd.uniquedf.index.get_level_values执行此操作,但这似乎有点垃圾:

In [66]: pd.unique(zip(df.index.get_level_values(0), df.index.get_level_values(1)))
Out[66]: array([(1, 'foo'), (2, 'foo'), (2, 'bar'), (3, 'foo'), (3, 'bar')], dtype=object)

有没有"很好"方式是什么?

3 个答案:

答案 0 :(得分:5)

In [22]: df.reset_index().set_index(['a','b']).index.unique()
Out[22]: array([(1, 'foo'), (2, 'foo'), (2, 'bar'), (3, 'foo'), (3, 'bar')], dtype=object)

答案 1 :(得分:3)

您可以在多索引上调用drop_level,然后在unique调用以获取所需的列表:

In [126]:    
df.index.droplevel('c').unique()

Out[126]:
array([(1, 'foo'), (2, 'foo'), (2, 'bar'), (3, 'foo'), (3, 'bar')], dtype=object)

答案 2 :(得分:1)

以与数据列相同的方式访问索引列很困难,因此如果在尝试之前重置索引,问题会变得更加容易:

>>> dff = df.reset_index()

dff现在看起来像这样:

   a    b    c  hi
0  1  foo  baz   0
1  1  foo  can   1
2  2  foo  baz   4
3  2  foo  can   5
4  2  bar  baz   6
5  2  bar  can   7
6  3  foo  baz   8
7  3  foo  can   9
8  3  bar  baz  10
9  3  bar  can  11

现在获取所需的值相对简单。我的第一次摸索尝试是:

>>> pd.unique(zip(dff.a, dff.b))
array([(1, 'foo'), (2, 'foo'), (2, 'bar'), (3, 'foo'), (3, 'bar')], dtype=object)

这更具可读性,但正如@LondonRob指出的那样,重置索引后,无需将列压缩在一起;只需使用列名列表作为索引,就可以从原始表中获得相同的结果,而无需将重新索引的DataFrame绑定到变量:

>>> pd.unique(df.reset_index()[['a', 'b']].values)
array([(1, 'foo'), (2, 'foo'), (2, 'bar'), (3, 'foo'), (3, 'bar')], dtype=object)