pandas
dataframe
string manipulation
data cleaning
python programming

How to split a dataframe string column into two 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.

Practice ML system design

Introduction

Splitting one pandas string column into two columns is a standard data-cleaning task. The right method depends on whether the separator is simple, whether every row has the same shape, and whether you need strict validation or flexible parsing.

For most cases, Series.str.split with expand=True is the direct answer. When the data is messier, str.extract with a regular expression often gives you better control.

Split on a Fixed Delimiter

If each value contains a predictable delimiter such as a comma, dash, or space, use str.split.

python
1import pandas as pd
2
3df = pd.DataFrame({
4    "location": ["Toronto,Canada", "Paris,France", "Tokyo,Japan"]
5})
6
7df[["city", "country"]] = df["location"].str.split(",", n=1, expand=True)
8print(df)

Output:

text
1         location     city  country
20  Toronto,Canada  Toronto   Canada
31    Paris,France    Paris   France
42     Tokyo,Japan    Tokyo    Japan

expand=True tells pandas to return multiple columns instead of a series of lists. n=1 limits the split to one separator, which is useful when the second part may contain the delimiter again.

Split Full Names or Similar Text

For values like "Ada Lovelace" or "Grace Hopper", the same pattern works:

python
1import pandas as pd
2
3df = pd.DataFrame({
4    "full_name": ["Ada Lovelace", "Grace Hopper", "Barbara Liskov"]
5})
6
7df[["first_name", "last_name"]] = df["full_name"].str.split(" ", n=1, expand=True)
8print(df)

Using n=1 is important here. Without it, names with extra spaces can produce more columns than expected.

Use str.extract for Irregular Data

If the input is inconsistent, a regular expression is often safer. Suppose values look like "item=42|status=ok":

python
1import pandas as pd
2
3df = pd.DataFrame({
4    "raw": ["item=42|status=ok", "item=18|status=failed"]
5})
6
7df[["item_id", "status"]] = df["raw"].str.extract(r"item=(\d+)\|status=([A-Za-z]+)")
8print(df)

str.extract makes your assumptions explicit. If a row does not match, pandas fills the extracted columns with missing values instead of silently producing partial lists.

That is often preferable in production pipelines because invalid rows become visible.

Handle Missing Values and Extra Whitespace

Real data is rarely clean. You may need to trim whitespace and protect against missing values:

python
1import pandas as pd
2
3df = pd.DataFrame({
4    "location": [" New York , USA ", None, "Berlin,Germany"]
5})
6
7parts = df["location"].fillna("").str.split(",", n=1, expand=True)
8df["city"] = parts[0].str.strip().replace("", pd.NA)
9df["country"] = parts[1].str.strip().replace("", pd.NA)
10
11print(df)

This keeps the pipeline resilient. Instead of failing on None, it converts missing input into missing output cleanly.

Choose the Right Assignment Style

If you know you want exactly two columns, explicit assignment is clear:

python
df[["left", "right"]] = df["value"].str.split("-", n=1, expand=True)

If the number of pieces varies and you want all of them, assign the full split result to a new DataFrame and rename later. That avoids hard-coding a column count that the source data does not actually guarantee.

Also note that str.split returns strings. If one side should be numeric, convert it explicitly with pd.to_numeric.

Common Pitfalls

  • Forgetting expand=True, which leaves you with a single series of Python lists instead of separate columns.
  • Assuming every row contains the delimiter. Rows without it can produce missing values or unexpected shapes.
  • Splitting on every occurrence when only the first separator matters. Use n=1 for safer behavior.
  • Ignoring whitespace, which leaves columns looking correct visually but failing equality checks later.

Summary

  • Use str.split(..., expand=True) when the delimiter is predictable.
  • Add n=1 when you only want two columns and the rest of the string should stay intact.
  • Use str.extract when the input is irregular and a regex describes the structure better.
  • Clean whitespace and missing values explicitly before or after the split.
  • Convert extracted values to numeric or datetime types if the downstream code depends on them.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track 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.

Practice ML system design

All Rights Reserved.