2013-09-16 2 views
40

У меня есть многоиндексный кадр данных с столбцами «A» и «B».выбор из multi-index pandas

Есть ли способ выбора строк путем фильтрации по одному столбцу мультииндекса без переустановки индекса к индексу одного столбца.

Для примера.

# has multi-index (A,B) 
df 
#can i do this? I know this doesnt work because index is multi-index so I need to  specify a tuple 

df.ix[df.A ==1] 
+0

возможный дубликат [ Как обновить подмножество MultiIndexed pandas DataFrame] (http://stackoverflow.com/questions/17552997/how-to-upda te-a-subset-of-a-multiindexed-pandas-dataframe) –

+0

Неясно, находится ли ваш MultiIndex в столбцах или строках. Похоже, это столбцы, но я не уверен. Вы можете уточнить? –

ответ

56

Один из способов заключается в использовании метода get_level_values Index:

In [11]: df 
Out[11]: 
    0 
A B 
1 4 1 
2 5 2 
3 6 3 

In [12]: df.iloc[df.index.get_level_values('A') == 1] 
Out[12]: 
    0 
A B 
1 4 1 

В 0.13 вы будете иметь возможность использовать xs with drop_level argument:

df.xs(1, level='A', drop_level=False) # axis=1 if columns 

Примечание: если это столбец мультииндексных скорее чем индекс, вы можете использовать тот же метод:

In [21]: df1 = df.T 

In [22]: df1.iloc[:, df1.columns.get_level_values('A') == 1] 
Out[22]: 
A 1 
B 4 
0 1 
19

Вы можете использовать DataFrame.xs():

In [36]: df = DataFrame(np.random.randn(10, 4)) 

In [37]: df.columns = [np.random.choice(['a', 'b'], size=4).tolist(), np.random.choice(['c', 'd'], size=4)] 

In [38]: df.columns.names = ['A', 'B'] 

In [39]: df 
Out[39]: 
A  b    a 
B  d  d  d  d 
0 -1.406 0.548 -0.635 0.576 
1 -0.212 -0.583 1.012 -1.377 
2 0.951 -0.349 -0.477 -1.230 
3 0.451 -0.168 0.949 0.545 
4 -0.362 -0.855 1.676 -2.881 
5 1.283 1.027 0.085 -1.282 
6 0.583 -1.406 0.327 -0.146 
7 -0.518 -0.480 0.139 0.851 
8 -0.030 -0.630 -1.534 0.534 
9 0.246 -1.558 -1.885 -1.543 

In [40]: df.xs('a', level='A', axis=1) 
Out[40]: 
B  d  d 
0 -0.635 0.576 
1 1.012 -1.377 
2 -0.477 -1.230 
3 0.949 0.545 
4 1.676 -2.881 
5 0.085 -1.282 
6 0.327 -0.146 
7 0.139 0.851 
8 -1.534 0.534 
9 -1.885 -1.543 

Если вы хотите сохранить A уровень (drop_level ключевое слово аргумент доступен только начиная с v0.13.0):

In [42]: df.xs('a', level='A', axis=1, drop_level=False) 
Out[42]: 
A  a 
B  d  d 
0 -0.635 0.576 
1 1.012 -1.377 
2 -0.477 -1.230 
3 0.949 0.545 
4 1.676 -2.881 
5 0.085 -1.282 
6 0.327 -0.146 
7 0.139 0.851 
8 -1.534 0.534 
9 -1.885 -1.543 
+1

Ха, я только что обновил свой ответ, Примечание: доступно только в 0.13. –

+0

О, хорошо знать. Я никогда не помню, какие маленькие удобства добавлены в каждой версии. –

+0

Lol, на самом деле этот вопрос является обманом того, кто вдохновил это удобство! :) –

0

Это старый вопрос , поэтому, как дополнение к существующим ответам, вы также можете использовать query, который более читабельен по моему мнению и прост в использовании:

import pandas as pd 

df = pd.DataFrame({'A': [1, 2, 3, 4], 'B': [10, 20, 50, 80], 'C': [6, 7, 8, 9]}) 
df = df.set_index(['A', 'B']) 

     C 
A B  
1 10 6 
2 20 7 
3 50 8 
4 80 9 

За то, что вы имели в виду, теперь вы можете просто сделать:

df.query('A == 1') 

     C 
A B  
1 10 6 

Вы также можете иметь более сложные запросы, используя and

df.query('A >= 1 and B >= 50') 

     C 
A B  
3 50 8 
4 80 9 

и or

df.query('A == 1 or B >= 50') 

     C 
A B  
1 10 6 
3 50 8 
4 80 9 
Смежные вопросы