How to flatten a hierarchical index in columns
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.
Introduction
To flatten a hierarchical (MultiIndex) column index in a Pandas DataFrame, join the level names into single strings using a list comprehension like ['_'.join(col).strip() for col in df.columns]. This converts multi-level column headers (e.g., ('price', 'mean')) into flat strings (e.g., 'price_mean'). Flattening is commonly needed after groupby().agg() operations that create MultiIndex columns, or before exporting to CSV/Excel where hierarchical columns are not supported.
How MultiIndex Columns Are Created
The resulting DataFrame has two-level column headers. Accessing columns requires tuples: summary[('price', 'mean')].
Method 1: Join Column Levels with Underscore
This is the most common approach. '_'.join(col) concatenates each tuple's elements with an underscore.
Method 2: get_level_values (Keep One Level)
Use get_level_values() when one level provides sufficient information. Be careful with the first level — it often produces duplicate column names.
Method 3: droplevel
droplevel() removes one level entirely. Use this when one level is redundant.
Method 4: map with f-string or Format
Using map gives full control over how level names are combined.
Method 5: to_flat_index (Pandas 0.24+)
to_flat_index() converts the MultiIndex to a regular Index of tuples, which you can then format as needed.
Method 6: reset_index with Named Aggregations
Avoid MultiIndex columns entirely by using named aggregations:
Named aggregations produce flat columns directly — no flattening step needed. This is the cleanest approach when you know the aggregations upfront.
Flattening Row MultiIndex
The same techniques work for hierarchical row indices:
Three or More Levels
The '_'.join(col) pattern works regardless of how many levels the MultiIndex has.
Common Pitfalls
- Empty string levels: After some operations, one level may contain empty strings.
'_'.join(('price', ''))produces'price_'with a trailing underscore. Use.strip('_')to clean it:['_'.join(col).strip('_') for col in df.columns]. - Duplicate column names after flattening: If you use
get_level_values(0), columns like('price', 'mean')and('price', 'sum')both become'price'. Pandas allows duplicate column names but operations on them become ambiguous. - Numeric level values: If levels contain numbers (e.g., year as int),
'_'.join()fails becausejoinrequires strings. Convert first:['_'.join(str(c) for c in col) for col in df.columns]. - Forgetting to flatten before to_csv:
df.to_csv()writes MultiIndex columns as multiple header rows, which can confuse downstream tools. Flatten before exporting. - reset_index surprises:
df.reset_index()flattens the row index but not the column index. To flatten both, flatten columns first, then callreset_index().
Summary
- Flatten MultiIndex columns with
df.columns = ['_'.join(col).strip() for col in df.columns] - Use
get_level_values()ordroplevel()to keep or remove specific levels - Use
mapwith a lambda for custom name formatting - Named aggregations (
agg(name=('col', 'func'))) avoid MultiIndex columns entirely - The
'_'.join()pattern works for any number of levels - Always check for empty strings, duplicates, and non-string level values after flattening
Related reading
- How to flatten only some dimensions of a numpy array
- How to form tuple column from two columns in Pandas
- How to generate a train-test-split based on a group id?
- How to get a colorbar in networkx.draw_networkx?
- How to format a floating number to fixed width in Python
- How to generate a temporary url to upload file to Amazon S3 with boto library?
- How to get a normal distribution within a range in numpy?
- How to get a specific sequence like this?
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.