How to Merge Two Columns in pandas (+, str.cat, agg)

To merge two columns in pandas, add them with + and a separator string. A sales team recently wanted one mailing-label column from separate city and state fields, and that one line did it.

It breaks when a ZIP code is an integer or a name is missing: you get a TypeError or a silent NaN.

Quick answer: add the columns with + and put a separator string between them. Convert non-text columns with astype(str) first:

df["location"] = df["city"] + ", " + df["state"]

In this tutorial, I’ll show you how to merge two columns pandas style on one customer table: text, numbers, missing values, three or more columns, and filling gaps.

How to Merge Two Text Columns in pandas with +

The running sample is four US customers, tested with Python 3.12.5 with pandas 3.0.6. For new-column basics, see my guide on adding a column to a pandas DataFrame covers the basics.

import pandas as pd

df = pd.DataFrame({
    "first_name": ["Emily", "James", "Olivia", "Marcus"],
    "last_name": ["Carter", "Nguyen", None, "Reed"],
    "city": ["Austin", "Denver", "Boston", "Miami"],
    "state": ["TX", "CO", "MA", "FL"],
    "zip": [73301, 80202, 2134, 33101],
})

df["location"] = df["city"] + ", " + df["state"]
df["full_name"] = df["first_name"] + " " + df["last_name"]
print(df[["location", "full_name"]])

Output:

     location     full_name
0  Austin, TX  Emily Carter
1  Denver, CO  James Nguyen
2  Boston, MA           NaN
3   Miami, FL   Marcus Reed
Command Prompt output of pandas merging city and state columns and first and last name columns with the + operator
Every location merges cleanly, but Olivia’s full name comes out as NaN because her last name is missing.

Merge a Text Column with a Number Column

pandas won’t add text to the integer zip column, so convert with astype(str). More conversions are in changing a column data type in pandas.

import pandas as pd

df = pd.DataFrame({
    "first_name": ["Emily", "James", "Olivia", "Marcus"],
    "last_name": ["Carter", "Nguyen", None, "Reed"],
    "city": ["Austin", "Denver", "Boston", "Miami"],
    "state": ["TX", "CO", "MA", "FL"],
    "zip": [73301, 80202, 2134, 33101],
})

try:
    df["state_zip"] = df["state"] + " " + df["zip"]
except TypeError as e:
    print("TypeError:", str(e).splitlines()[0][:70])

df["state_zip"] = df["state"] + " " + df["zip"].astype(str).str.zfill(5)
print(df[["state", "zip", "state_zip"]])

Output:

TypeError: can only concatenate str (not "int") to str
  state    zip state_zip
0    TX  73301  TX 73301
1    CO  80202  CO 80202
2    MA   2134  MA 02134
3    FL  33101  FL 33101
Command Prompt output of a pandas TypeError when adding a string column to an int column, then the fix with astype(str) and zfill
The plain + raises a TypeError; after astype(str).str.zfill(5), Boston’s ZIP keeps its leading zero.

How Do You Merge Columns with Missing Values?

Use Series.str.cat() with na_rep="" (missing becomes empty text), then str.strip() the leftover space:

import pandas as pd

df = pd.DataFrame({
    "first_name": ["Emily", "James", "Olivia", "Marcus"],
    "last_name": ["Carter", "Nguyen", None, "Reed"],
    "city": ["Austin", "Denver", "Boston", "Miami"],
    "state": ["TX", "CO", "MA", "FL"],
    "zip": [73301, 80202, 2134, 33101],
})

df["full_name"] = df["first_name"].str.cat(df["last_name"], sep=" ", na_rep="")
df["full_name"] = df["full_name"].str.strip()
print(df[["first_name", "last_name", "full_name"]])

Output:

  first_name last_name     full_name
0      Emily    Carter  Emily Carter
1      James    Nguyen  James Nguyen
2     Olivia       NaN        Olivia
3     Marcus      Reed   Marcus Reed
Command Prompt output of pandas str.cat with sep and na_rep merging first and last name columns when one value is missing
Olivia now gets Olivia instead of NaN, and the other three names are unchanged.

Plain Python strings work differently; see concatenating strings in Python.

Merge Three or More Columns into One

agg(", ".join, axis=1) joins any number of string columns per row:

import pandas as pd

df = pd.DataFrame({
    "first_name": ["Emily", "James", "Olivia", "Marcus"],
    "last_name": ["Carter", "Nguyen", None, "Reed"],
    "city": ["Austin", "Denver", "Boston", "Miami"],
    "state": ["TX", "CO", "MA", "FL"],
    "zip": [73301, 80202, 2134, 33101],
})

df["zip5"] = df["zip"].astype(str).str.zfill(5)
df["address"] = df[["city", "state", "zip5"]].agg(", ".join, axis=1)
print(df["address"].tolist())

Output:

['Austin, TX, 73301', 'Denver, CO, 80202', 'Boston, MA, 02134', 'Miami, FL, 33101']

To break a merged column apart again, see splitting a pandas column by a delimiter.

Fill One Column’s Gaps from Another with combine_first()

To keep the mobile number and fall back to the home number only when mobile is blank, use combine_first():

import pandas as pd

df = pd.DataFrame({
    "name": ["Emily", "James", "Olivia", "Marcus"],
    "mobile": ["512-555-0142", None, "617-555-0199", None],
    "home": [None, "303-555-0117", "617-555-0100", None],
})
df["phone"] = df["mobile"].combine_first(df["home"])
print(df)

Output:

     name        mobile          home         phone
0   Emily  512-555-0142           NaN  512-555-0142
1   James           NaN  303-555-0117  303-555-0117
2  Olivia  617-555-0199  617-555-0100  617-555-0199
3  Marcus           NaN           NaN           NaN
Command Prompt output of pandas combine_first merging a mobile phone column and a home phone column into one phone column
Emily and Olivia keep their mobile numbers, James gets his home number, and Marcus stays empty.

Don’t confuse this with combining two tables. Joining DataFrames on a key is pandas merge and join, and stacking them is concatenating two DataFrames.

Common Errors When Merging pandas Columns

  • TypeError with +: one column is numeric. Add astype(str).
  • NaN in the result: a source value is missing. Use str.cat(na_rep="") or fillna("").
  • ZIP like 2134.0: the column is float. Use astype("Int64") first.

When you’re cleaning up pandas columns, these walk-throughs come in handy:

Frequently Asked Questions

How do I merge two columns in pandas?

Use df["a"] + " " + df["b"].

How do I combine a string column and an int column?

Convert the number first: df["a"] + df["n"].astype(str).

Why does merging columns give NaN?

+ returns NaN when either value is missing. Use str.cat(sep=" ", na_rep="").

How do I merge more than two columns?

Use df[["a", "b", "c"]].agg(", ".join, axis=1) on string columns.

Is pd.merge() used to merge two columns?

No. pd.merge() joins two DataFrames on keys. To combine columns inside one DataFrame, use + or str.cat().

Where is str.cat documented?

See Series.str.cat() in the pandas docs.