Q&A library Python

How do I get pandas to choose better types for my columns?

Python Advanced convert-dtypesdtypesnullable

Short answer

convert_dtypes moves columns to the nullable types, so integers stay integers even with missing values and text becomes a proper string dtype. It is a good tidy-up after reading messy data.

The short version

convert_dtypes() converts each column to the best available nullable type. Integer columns stay integers even when they contain missing values, and text columns become a proper string dtype instead of the vague object. It is a useful tidy-up step after loading messy data.

What it does

import pandas as pd

df = pd.DataFrame({"a": [1, None]})

df.dtypes                     # float64 , the None forced it to float
df.convert_dtypes().dtypes    # Int64 , a nullable integer

Without conversion, a single missing value drags an integer column to float, so your counts and identifiers become 1.0 and 2.0. convert_dtypes uses the nullable Int64 type, which holds integers and missing values, so the numbers stay whole.

Why the object dtype is unhelpful

A text column normally has dtype object, which means "arbitrary Python objects" and tells you nothing. It could contain strings, or a mixture of strings and numbers, or anything at all. The string dtype introduced by convert_dtypes is explicit, catches type mistakes earlier, and makes the .str methods behave more predictably with missing values.

When to use it

Straight after reading a file is the natural place, once you have parsed the dates and handled placeholders.

df = (
    pd.read_csv("orders.csv", na_values=["", "NA", "-"])
      .convert_dtypes()
)

This gives you a frame where the types reflect what the data actually is, which makes every subsequent step safer.

The caveats

It is not a silver bullet. Two things to know.

First, it will not convert a column of numbers stored as text into numbers, because that requires parsing, not just a type change. You still need pd.to_numeric for that, and convert_dtypes will happily leave a numeric-looking text column as string.

Second, some older libraries do not fully understand the nullable dtypes and may complain or behave oddly when handed an Int64 column. If a downstream tool objects, convert back at that boundary with astype.

Doing it per column

You do not have to convert everything at once. For a single column where you specifically need integers with missing values, cast directly.

df["count"] = pd.to_numeric(df["count"], errors="coerce").astype("Int64")

Note the capital I. The lowercase int64 is the old, non-nullable type and will raise if the column contains missing values.

Check the result

As with any type change, look at what you got.

df.dtypes

Types are the foundation everything else rests on. A column that is silently text when you thought it was numeric, or float when you thought it was integer, will cause a subtle failure somewhere downstream. Spending a minute confirming the types after loading is one of the highest-value habits in data work.

Need this solved on your own data?

The library is free and always will be. When the problem is bigger than an answer, we take on the work.

Start a project