pandas
data manipulation
Python
dataframe transformation
dictionary columns

Split / Explode a column of dictionaries into separate columns with pandas

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

If a pandas column contains dictionaries, the usual goal is to turn each dictionary key into a normal DataFrame column. The cleanest solution is to normalize that column and join the result back to the original frame.

The Basic Pattern

Suppose a DataFrame has a details column where each row contains a dictionary.

python
1import pandas as pd
2
3
4df = pd.DataFrame({
5    "id": [1, 2, 3],
6    "details": [
7        {"name": "Alice", "age": 25},
8        {"name": "Bob", "age": 30},
9        {"name": "Cara", "age": 28},
10    ],
11})
12
13expanded = pd.json_normalize(df["details"])
14result = pd.concat([df.drop(columns=["details"]), expanded], axis=1)
15print(result)

Output:

text
1   id   name  age
20   1  Alice   25
31   2    Bob   30
42   3   Cara   28

pd.json_normalize() is usually the best option because it is explicit and works well when dictionaries become more nested later.

apply(pd.Series) Also Works

For shallow dictionaries, you will often see this pattern:

python
expanded = df["details"].apply(pd.Series)
result = df.drop(columns=["details"]).join(expanded)

This is readable and works well for simple cases. In practice, json_normalize is often the more flexible choice, especially if nested fields appear later.

Missing Keys Become Missing Values

Dictionary keys do not need to match perfectly across rows. Pandas will align by key name and fill missing values with NaN.

python
1import pandas as pd
2
3
4df = pd.DataFrame({
5    "details": [
6        {"name": "Alice", "age": 25},
7        {"name": "Bob"},
8        {"name": "Cara", "city": "Toronto"},
9    ]
10})
11
12expanded = pd.json_normalize(df["details"])
13print(expanded)

That behavior is usually what you want, but it means you may need to clean missing values afterward.

python
expanded = expanded.fillna({"age": 0, "city": "unknown"})

If The Column Contains JSON Strings, Parse First

Sometimes the column looks like dictionaries but actually contains strings.

python
1import json
2import pandas as pd
3
4
5df = pd.DataFrame({
6    "details": [
7        '{"name": "Alice", "age": 25}',
8        '{"name": "Bob", "age": 30}'
9    ]
10})
11
12df["details"] = df["details"].apply(json.loads)
13expanded = pd.json_normalize(df["details"])
14print(expanded)

If you skip parsing, pandas treats the values as plain strings and cannot split them into columns.

Distinguish A Dictionary Column From A List Column

The title often says "explode," but explode() is mainly for list-like values, not dictionaries.

Use:

  • 'json_normalize or apply(pd.Series) for a column of dictionaries'
  • 'explode() for a column of lists'

If you have a list of dictionaries, you may need both steps.

python
1import pandas as pd
2
3
4df = pd.DataFrame({
5    "id": [1],
6    "items": [[{"name": "A", "qty": 2}, {"name": "B", "qty": 5}]],
7})
8
9exploded = df.explode("items", ignore_index=True)
10expanded = pd.json_normalize(exploded["items"])
11result = pd.concat([exploded.drop(columns=["items"]), expanded], axis=1)
12print(result)

This distinction prevents a lot of confusion.

Keep Column Names Predictable

If the dictionaries are nested, json_normalize can create dotted column names such as address.city. That is often useful, but you may want to rename them afterward.

python
expanded = pd.json_normalize(df["details"])
expanded = expanded.rename(columns={"address.city": "city"})

Clean column names early so later analysis stays readable.

Common Pitfalls

The most common mistake is calling explode() on a dictionary column. That is the wrong tool unless the values are lists.

Another mistake is forgetting to parse JSON strings before normalization.

Developers also sometimes expand the dictionaries correctly but forget to drop the original column, leaving duplicated information in the frame.

Finally, missing keys are normal. Treat the resulting NaN values as part of the transformation, not as a sign that pandas failed.

Summary

  • Use pd.json_normalize() to split a dictionary column into normal columns.
  • 'apply(pd.Series) is fine for simple flat dictionaries.'
  • Parse JSON strings with json.loads before expanding them.
  • Use explode() only for list-like columns, not plain dictionaries.
  • Expect missing keys to produce NaN and clean them afterward if needed.

Course illustration
Course illustration

All Rights Reserved.