pandas
python
data manipulation
data analysis
data type conversion

How to change datatype of multiple columns in pandas

Master System Design with Codemia

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

Introduction

Changing multiple pandas column types at once is common in ingestion and cleanup pipelines, but the right method depends on how clean the input really is. Some columns can be converted directly with astype, while others should go through parser helpers such as to_numeric or to_datetime so invalid values are handled deliberately instead of causing confusing downstream bugs.

Use astype When the Data Is Already Clean

If the values are already valid for the target types, astype with a dictionary is the most concise solution.

python
1import pandas as pd
2
3df = pd.DataFrame({
4    "id": ["1", "2", "3"],
5    "price": ["10.5", "21.0", "7.25"],
6    "active": [True, False, True],
7})
8
9df = df.astype({
10    "id": "int64",
11    "price": "float64",
12})
13
14print(df)
15print(df.dtypes)

This works well when the source is trustworthy. If one value is malformed, pandas raises immediately, which is often exactly what you want in a strict pipeline.

Use Parser Helpers for Dirty Columns

Real-world input is usually less cooperative. Numeric columns may contain empty strings, text placeholders, or unexpected punctuation. Date columns may contain invalid timestamps. In those cases, astype is often too blunt.

python
1import pandas as pd
2
3df = pd.DataFrame({
4    "amount": ["100", "200", "bad", None],
5    "created_at": ["2026-03-01", "2026-03-02", "invalid", "2026-03-04"],
6})
7
8df["amount"] = pd.to_numeric(df["amount"], errors="coerce")
9df["created_at"] = pd.to_datetime(df["created_at"], errors="coerce")
10
11print(df)
12print(df.dtypes)

Using errors="coerce" turns bad values into missing values instead of stopping the whole process. That makes later validation more explicit, because you can count or inspect the failed conversions directly.

Convert Groups of Columns Programmatically

When several columns share the same conversion rule, group them by intent instead of repeating similar code manually.

python
1numeric_cols = ["qty", "score"]
2date_cols = ["created_at", "updated_at"]
3
4for col in numeric_cols:
5    df[col] = pd.to_numeric(df[col], errors="coerce")
6
7for col in date_cols:
8    df[col] = pd.to_datetime(df[col], errors="coerce")

This pattern is clearer than forcing every column through one giant expression, especially when one group contains numbers and another contains timestamps.

Nullable Types Matter

A common surprise is that plain NumPy integer types cannot hold missing values. If the column contains blanks, a direct cast to int64 will fail or push the data toward float representation.

Use pandas nullable dtypes instead:

python
1import pandas as pd
2
3df = pd.DataFrame({
4    "count": ["1", None, "3"],
5    "flag": [True, None, False],
6})
7
8df["count"] = pd.to_numeric(df["count"], errors="coerce").astype("Int64")
9df["flag"] = df["flag"].astype("boolean")
10
11print(df)
12print(df.dtypes)

This preserves integer or boolean semantics while still allowing nulls.

convert_dtypes() Can Be a Good First Pass

If your goal is to improve a messy imported frame before stricter conversion, convert_dtypes() is a useful middle ground.

python
df = df.convert_dtypes()
print(df.dtypes)

It often upgrades object columns into pandas string, nullable integer, or nullable boolean types. That is not the same as defining a final schema, but it can be a helpful cleanup step before targeted conversions.

Selecting Columns Automatically

Sometimes you want to convert all object columns to a newer string dtype or all integer-like columns to nullable types. Selection helpers can reduce repetition.

python
object_cols = df.select_dtypes(include=["object"]).columns
df[object_cols] = df[object_cols].astype("string")

This is convenient, but it should be used carefully. If the upstream schema changes, a broader selection rule can touch columns you did not intend to convert.

Validate After Conversion

A conversion step is not complete just because no exception was raised. You should verify the resulting dtypes and inspect how many values became missing during coercion.

python
print(df.dtypes)
print(df.isna().sum())

For critical pipelines, add assertions:

python
assert str(df["created_at"].dtype).startswith("datetime64")
assert str(df["count"].dtype) == "Int64"

Those checks catch upstream schema drift early, before bad types spread into joins, aggregations, or model training code.

Common Pitfalls

  • Using astype on dirty columns that really need parsing helpers.
  • Casting nullable integer data to plain int64 and failing on missing values.
  • Applying one conversion rule to every column even though formats differ.
  • Auto-selecting columns too broadly and converting data unintentionally.
  • Skipping validation after conversion and discovering the type problem much later.

Summary

  • Use astype for clean, already-parseable columns.
  • Use to_numeric and to_datetime when conversion needs error handling.
  • Group columns by conversion strategy instead of forcing one rule across the whole frame.
  • Prefer pandas nullable dtypes when missing values must be preserved.
  • Validate the final dtypes and missing-value counts after conversion.

Course illustration
Course illustration

All Rights Reserved.