Main Ecosystems
HomePython CorePandas ReferenceNumPy ScientificFastAPI & PydanticDjango Enterprise
More Ecosystems
Environment & SetupRequests & HTTPAsyncIO ConcurrencyObject-Oriented OOPPyTorch Deep LearningScikit-Learn MLFlask FrameworkWeb ScrapingDatabase & ORMDevOps & Docker

Pandas: TypeError: can only concatenate str (not int) to str in Column Operations

Verified FixPython 3.10+Pandas 2.2+Silo: pandas

Quick Fix / Solution Rapide

This error occurs when Python tries to concatenate a text column with a numeric column using the + operator. Explicitly convert numeric columns to strings with .astype(str) or use Series.str.cat().

Root Cause Analysis

This error occurs when Python evaluates the binary addition operator + between a Pandas Series containing strings (object or string dtype) and a Series containing integers or floating-point numbers.

Root Cause 1: Operator Overloading in Python and Pandas

In Python, the + operator is overloaded: for integers and floats, + performs mathematical addition (e.g. 10 + 20 = 30), while for strings, + performs string concatenation (e.g. 'A' + 'B' = 'AB'). Python refuses to guess developer intent when adding a string to an integer ('ID_' + 101), raising TypeError: can only concatenate str (not "int") to str. Pandas maintains Python's strict type safety across vectorized operations.

Root Cause 2: Attempting Column Concatenation on Uncast Data

When generating composite keys or unique identifiers from multiple DataFrame columns (such as combining a country code "FR" with a numeric customer ID 4892), writing df['code'] = df['country'] + '_' + df['id'] fails on the second addition because df['id'] has integer dtype.

Root Cause 3: Hidden Mixed Types in Object Dtype Columns

If a column has object dtype and contains a mix of native Python strings and integers (for instance, loaded from an untyped JSON or Excel file), vectorized string operations like df['col'] + '_suffix' will succeed on the string rows but crash upon encountering the first integer row with a TypeError.

Root Cause 4: Null Values Converting to the String 'nan'

When converting numeric columns with missing values (NaN) to string using .astype(str), NaN values become literal four-character strings 'nan'. Downstream operations will produce values like 'USER_nan' instead of preserving missing value semantics.

Reproduction Code (MCVE)

Example: Bug Reproduction
import pandas as pd

# Creating a DataFrame with a string column and an integer column
df = pd.DataFrame({
    "prefix": ["USER_", "ORDER_", "ITEM_"],
    "identifier": [101, 102, 103]
})

# Attempting to concatenate string and integer columns directly triggers TypeError
df["full_code"] = df["prefix"] + df["identifier"]

Solution 1: Cast the Numeric Column to String with .astype(str)

Convert the numeric column to string before applying the + concatenation operator, ensuring both operands have matching string dtypes.

Example: Recommended Solution
import pandas as pd

df = pd.DataFrame({
    "prefix": ["USER_", "ORDER_", "ITEM_"],
    "identifier": [101, 102, 103]
})

# Cast the numeric column to string before concatenation
df["full_code"] = df["prefix"] + df["identifier"].astype(str)

print("Concatenated DataFrame:")
print(df)

Solution 2: Use Series.str.cat() or Vectorized Formatted Strings

Use Series.str.cat() with custom separators or list comprehensions with f-strings for clean formatting across multiple columns.

Example: Alternative Solution
import pandas as pd

df = pd.DataFrame({
    "region": ["EU", "US", "APAC"],
    "year": [2024, 2025, 2024],
    "batch_id": [1, 2, 3]
})

# Option A: List comprehension with f-strings (fast for row-level string formatting)
df["sku_code"] = [f"{r}_{y}_B{b:03d}" for r, y, b in zip(df["region"], df["year"], df["batch_id"])]

# Option B: Series.str.cat with explicit casting
df["simple_key"] = df["region"].str.cat(df["year"].astype(str), sep="-")

print("Formatted composite keys:")
print(df[["region", "sku_code", "simple_key"]])

A dangerous edge case is handling missing values during string concatenation. If a column contains pd.NA or np.nan, col.astype(str) will turn pd.NA into the string '<NA>' and np.nan into 'nan'. To prevent creating corrupted strings like 'USER_nan', fill missing values first with .fillna('') or use df['col'].astype('string') (the dedicated StringDtype in Pandas) which propagates <NA> cleanly during .str.cat().

Another common mistake is confusing pd.concat() with column string concatenation: pd.concat([df1, df2]) appends rows or merges axes of DataFrames, whereas column string concatenation combines the text values within rows.

Contrast this TypeError with ValueError: cannot convert float NaN to integer: The TypeError is a syntax/operator contract violation between dissimilar types, while the ValueError occurs when casting non-finite numerical floats into integer storage.