我有一个像这样的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中出现a
和b
的哪些级别:
[(1, 'foo'), (2, 'foo'), (2, 'bar'), (3, 'foo'), (3, 'bar')]
我可以使用pd.unique
和df.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)
有没有"很好"方式是什么?
答案 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)