4

Set-up

I have a pandas dataframe df consisting out of multiple columns, with headers like,

| id | x, single room | x, double room | y, single room | y, double room |
--------------------------------------------------------------------------
   ⋮          ⋮               ⋮                 ⋮                 ⋮


Problem

I'd like to group the columns starting with x and starting with y under headers in the following way,

     |             x             |             y             |
--------------------------------------------------------------
| id | single room | double room | single room | double room |
--------------------------------------------------------------
   ⋮        ⋮             ⋮              ⋮             ⋮          

How do I go about?

1
  • This can be done (more or less) with MultiIndexing. Commented Apr 20, 2017 at 11:17

1 Answer 1

8

You can use split, but main problem is get id to last level:

col =['id','x, single room','x, double room','y, single room','y, double room' ]
df = pd.DataFrame([[1,1,1,1,1]], columns=col)
print (df)
   id  x, single room  x, double room  y, single room  y, double room
0   1               1               1               1               1

#create tuples from MultiIndex
a = df.columns.str.split(', ', expand=True).values
print (a)
[('id', nan) ('x', 'single room') ('x', 'double room') ('y', 'single room')
 ('y', 'double room')]

#swap values in NaN and replace NAN to ''
df.columns = pd.MultiIndex.from_tuples([('', x[0]) if pd.isnull(x[1]) else x for x in a])
print (df)
               x                       y            
  id single room double room single room double room
0  1           1           1           1           1

Old solution:

a = pd.DataFrame(df.columns.str.rsplit(', ', expand=True).values.tolist())
mask = a[1].isnull()
a.loc[mask, [0,1]] = a.loc[mask, [1,0]].values
a[0] = a[0].fillna('')
df.columns = a.set_index([0,1]).index
df.columns.names = ('', '')
Sign up to request clarification or add additional context in comments.

3 Comments

Great! Thank you.
I have nicer solution, give me a sec.
@jezrael It's really fantastic.

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.