在pandas中检索MultiIndex的一个级别的值

时间:2017-09-05 09:02:49

标签: python pandas multi-index

我有一个MultiIndex

ind = pd.MultiIndex.from_tuples([('A', 0), ('A', 1), ('B', 1), ('B', 2)], names=['Letters', 'Numbers'])

喜欢那个

Letters  Numbers
A        0
A        1
B        1
B        2

如果给出第一级的值,我如何检索第二级的所有值?也就是说,给定A,我想得到[0,1],给定B,我想得到[1,2]。

我能想到的唯一方法是

ind.get_level_values(1)[ind.get_level_values(0) == 'B']

但这看起来不太好,我希望有一个更优雅的表达方式。有吗?

1 个答案:

答案 0 :(得分:2)

最简单,最快的是使用列表理解:

a = [x[1] for x in ind.tolist() if x[0] == 'A']
print (a)

[0, 1]

另一种可能的解决方案是使用boolean indexing创建帮助df

df = pd.DataFrame(ind.tolist(), columns=['a','b'])
print (df)
   a  b
0  A  0
1  A  1
2  B  1
3  B  2

a = df.loc[df['a'] == 'A', 'b'].tolist()
print (a)
[0, 1]

a = df.loc[df['a'] == 'B', 'b'].tolist()
print (a)
[1, 2]

但在我看来,你的解决方案很好(按级别名称选择有点改变):

a = ind.get_level_values('Numbers')[ind.get_level_values('Letters') == 'B'].tolist()
print (a)
[1, 2]

<强>计时

In [197]: %timeit ([x[1] for x in ind.tolist() if x[0] == 'A'])
100000 loops, best of 3: 2.14 µs per loop

In [199]: %timeit ind.get_level_values('Numbers')[ind.get_level_values('Letters') == 'B'].tolist()
1000 loops, best of 3: 377 µs per loop


In [200]: %%timeit
     ...: df = pd.DataFrame(ind.tolist(), columns=['a','b'])
     ...: df.loc[df['a'] == 'A', 'b'].tolist()
     ...: 
1000 loops, best of 3: 1.06 ms per loop