Pandas filter MultiIndex on part of MultiIndex using .loc

Question:

I want to filter a DataFrame using only 2 levels of a 3-level MultiIndex. Is there a way cant find a way to do that with .loc?

The only way I managed to do that is the following:

df=pd.DataFrame(index=pd.MultiIndex.from_tuples([(1,'a','x')
,(1,'a','y')
,(1,'b','z')
,(1,'b','x')
,(2,'c','y')
,(2,'c','z')
,(2,'a','x')
,(2,'a','y')
,(3,'b','z')
,(3,'b','x')
,(3,'c','y')
,(3,'c','z')]), 
data=[20,26,43,20,65,40,87,41,84,50,5,54])

f=[(2, 'a'), (3, 'b'), (3, 'c')]

df=df.reset_index(level=2).loc[f].reset_index().set_index(['level_0','level_1','level_2'])

resulting df is:

0
level_0 level_1 level_2
2 a x 87
y 41
3 b z 84
x 50
c z 5
x 54

What I want is to be able to do something like df.loc[(f,slice(None))] to make the code a bit less complicated

Asked By: JohnnieL

||

Answers:

IIUC you still can achieve that, you just have to structure your tuple correctly inside loc.

df.loc[([2, 3], ["a", "b"], ), :]

Output:

        0
2 a x  87
    y  41
3 b z  84
    x  50
Answered By: Tranbi

i think f is not appropriate example becuz a and b do not overlap in 2 and 3

Let’s take a from 1 and only b from 3 (becuz 1 also has b)

idx = [(1, 'a'), (3, 'b')]
df[df.index.droplevel(2).isin(idx)]

result:

            0
1   a   x   20
        y   26
3   b   z   84
        x   50
Answered By: Panda Kim
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.