2017-01-23 2 views
2

У меня есть dataframe в такой форме:Получить столбцы из мультииндексного dataframe с именованными этикетками

first  bar       foo      
second  one  two  three  one  two  three 
0  -2.008137 0.505892 -0.671299 -1.289395 -1.087887 -0.146657 
1  -0.786329 -0.501268 -1.454408 2.627911 0.689416 -0.877968 
2  -0.697007 0.929783 0.181715 0.533407 0.117859 -0.557975 
3  -1.276656 -0.405381 -0.674329 0.117411 1.536421 0.040912 

Я хочу, чтобы выбрать данные с индексами на основе одного названия уровня, как это:

selected = data.xs(('bar', 'two'), level = ['first','second'], axis=1) 

Это работает. Тем не менее, я хотел бы выбрать несколько меток таким образом. Что-то вроде:

selected = data.xs(('bar', ['one','two']), level = ['first','second'], axis=1) 

для того, чтобы получить:

first  bar     
second  one  two 
0  -2.008137 0.505892 
1  -0.786329 -0.501268 
2  -0.697007 0.929783 
3  -1.276656 -0.405381 

Это, однако, не работает. Как я могу элегантно выбирать данные таким образом? Важно, чтобы я мог использовать имена уровней («первый» и «второй»).

ответ

2

Вы можете использовать slicers:

#KeyError: 'MultiIndex Slicing requires the index to be fully lexsorted  
df = df.sort_index(axis=1) 
idx = pd.IndexSlice 
print (df.loc[:, idx['bar', ['one','two']]]) 
first  bar   
second  one  two 
0  -2.008137 0.505892 
1  -0.786329 -0.501268 
2  -0.697007 0.929783 
3  -1.276656 -0.405381 

Другое решение:

df = df.sort_index(axis=1) 
print (df.loc[:, ('bar', ['one','two'])]) 
first  bar   
second  one  two 
0  -2.008137 0.505892 
1  -0.786329 -0.501268 
2  -0.697007 0.929783 
3  -1.276656 -0.405381 

Но если нужно выбирать с именами уровня использования get_level_values с isin, а затем выберите на boolean indexing (выберите столбцы, так loc необходимо):

mask1 = df.columns.get_level_values('first') == 'bar' 
mask2 = df.columns.get_level_values('second').isin(['one','two']) 
print (df.loc[:, mask1 & mask2]) 
first  bar   
second  one  two 
0  -2.008137 0.505892 
1  -0.786329 -0.501268 
2  -0.697007 0.929783 
3  -1.276656 -0.405381 
+0

Привет Спасибо за ответ, но мне нужно использовать имена уровня («первый» и «второй») – Benjamin

+0

Пожалуйста, проверьте отредактированный ответ. – jezrael

2

Вы можете использовать метод query но требует принятия транспонирование

data.T.query('first in ["bar", "foo"] and second in ["one", "two"]').T 
# ⤷ transpose here        transpose back ⤴ 

или вы можете установить эти переменные вне query и ссылки на них

first = ['bar', 'foo'] 
second = ['one', 'two'] 
data.T.query('first in @first and second in @second').T 
# ⤷ transpose here     transpose back ⤴ 

enter image description here


Heres меньше нас ред Альтернативой этой проблемы

data.filter(regex='one|two') 

enter image description here

+0

Привет Спасибо за ваш ответ, но мне нужно использовать имена уровней ('first' и 'second') – Benjamin

+0

@Ben Я обновил сообщение, как и jezrael. – piRSquared

Смежные вопросы