1

I have a df that looks like this:

mux = pd.MultiIndex(levels=[['A', 'B', 'C', 'D']],labels=[[2, 3, 0, 1]])
df = pd.DataFrame({'a':range(4)}, index=mux)

How can I drop the empty level to form a single-index df? I have tried

pd.MultiIndex.droplevel(df, level=0)

But got the following error:

AttributeError: 'DataFrame' object has no attribute 'levels'

Where did I get wrong?

I have also tried the following, but the index matching for some reason gets messed up (eg. the original row for 'A' is matched with 'B'), even it I use sort_index.

df.index=df.index.levels[0]
1
  • sort_index(inplace=True) worked. Commented Jul 26, 2018 at 12:35

1 Answer 1

1

Use get_level_values with assign back or with set_index because it is special type of MultiIndex with only one level:

mux = pd.MultiIndex(levels=[['A', 'B', 'C', 'D']],
       labels=[[2, 3, 0, 1]])

df = pd.DataFrame({'a':range(4)}, index=mux)
print (df)
   a
C  0
D  1
A  2
B  3

df.index = df.index.get_level_values(0)
print (df.index )
Index(['C', 'D', 'A', 'B'], dtype='object')

print (df)
   a
C  0
D  1
A  2
B  3

Or:

df = df.set_index(df.index.get_level_values(0))
print (df.index)
Index(['C', 'D', 'A', 'B'], dtype='object')
Sign up to request clarification or add additional context in comments.

4 Comments

I tried and got the error: ValueError: Must pass non-zero number of levels/labels
@edge27 - So problem with real data? In sample for me it working nice. I add output of df before and after. Or need something different?
Sorry I thought level[0] is equal to get_level_values(0), but apparently the latter takes care of the matching. So yes, it worked. Or if I use level[0], I need to sort_index first. The problem was I forgot inplace=True.
@edge27 - No problem, nice day!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.