Reputation: 3893
I 'm looking to slice a Pandas dataframe with a multi index by a list of values for some of the index levels.
import pandas as pd
index = pd.MultiIndex.from_product((('A','B'),
range(2),
('c','d')))
df = pd.DataFrame(index=index,columns=range(2))
slice_list = [('A',0),('B',1)]
This doesn't work:
df.loc[slice_list,:]
I can get my expected result by doing boolean masking(?):
idx = (((df.index.get_level_values(0) == 'A')
& (df.index.get_level_values(1) == 0)) |
((df.index.get_level_values(0) == 'B')
& (df.index.get_level_values(1) == 1)))
df.loc[idx]
0 1
A 0 c NaN NaN
d NaN NaN
B 1 c NaN NaN
d NaN NaN
But I would much prefer a slicing option.
Upvotes: 0
Views: 141
Reputation: 181
You can use pandas.IndexSlice
(https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.IndexSlice.html).
idx = pd.IndexSlice
slice = idx[['A','B'],[0,1],:]
df.loc[slice,:]
Or something along those lines, I am currently replying from a cell phone so I'm not 100% sure.
Upvotes: 0
Reputation: 862761
You can use Index.isin
with remove last level for 2 levels MultiIndex
:
df1 = df[df.index.droplevel(-1).isin(slice_list)]
print (df1)
0 1
A 0 c NaN NaN
d NaN NaN
B 1 c NaN NaN
d NaN NaN
Details:
print (df.index.droplevel(-1))
MultiIndex([('A', 0),
('A', 0),
('A', 1),
('A', 1),
('B', 0),
('B', 0),
('B', 1),
('B', 1)],
)
Upvotes: 1