Skip to main content
v2026.11,858 entries · CC-BY 4.0

pandas dtypes: Inspect, Convert and Choose Types

pandas dtypes explained: inspect with df.dtypes, convert with astype and to_numeric, handle the pandas 3 str change, and fix common errors.

Written and maintained by CASRAI Editorial Board

Last updated

pandas dtypes are the data types pandas assigns to each column of a Series or DataFrame. Inspect them with df.dtypes, convert them with astype(), pd.to_numeric() or pd.to_datetime(), and filter columns by type with select_dtypes(). This guide is for researchers and analysts loading survey, instrument or administrative exports into pandas who need every column to carry the type the analysis expects. Commands were checked against the pandas user guide and API reference, and the examples were run on pandas 3.0.5.

What dtypes are used for in research

A column’s dtype decides which operations work and how missing values are stored. A participant ID such as 007 stored as an integer loses its leading zeros; a Likert response exported as text cannot be averaged; a date left as a string cannot be sorted or resampled. Checking dtypes right after loading is a cheap data-quality step, and it belongs alongside the other data cleaning steps.

pandas supports two families of dtypes. NumPy-backed dtypes cover float, int, bool, timedelta64[ns] and datetime64[ns]; NumPy has no timezone-aware datetime. Extension dtypes add timezone-aware datetimes, categoricals, periods, intervals, sparse data, nullable integers and floats, strings and nullable booleans.

Install or access

pandas is open-source and installed from the official channels on the pandas installation page: pip install pandas or conda install -c conda-forge pandas. Confirm the version with import pandas as pd; print(pd.__version__), because string handling differs between pandas 2.x and 3.x (see “Strings: object versus str” below).

Step by step: inspect and convert dtypes

  1. Inspect. Run df.dtypes for one dtype per column, or df.info() for dtypes plus non-null counts.
  2. Convert with astype(). The signature is DataFrame.astype(dtype, copy=<no_default>, errors='raise'). Pass one dtype for the whole frame (df.astype("int32")) or a mapping from column name to dtype (df.astype({"col1": "int32"})); columns not in the mapping are unchanged, and a key that is not a column raises KeyError. A Series converts the same way: ser.astype("category").
  3. Convert dirty text with the to_* functions. pd.to_numeric, pd.to_datetime and pd.to_timedelta are the “hard” conversions and work on one-dimensional input (use df.apply for a whole frame). The default errors='raise' stops at the first bad value; errors='coerce' turns unparseable values into NaN or NaT. For example pd.to_numeric(["apple", 2, 3], errors="coerce") returns array([nan, 2., 3.]). For date parsing see pandas datetime.
  4. Let pandas infer with infer_objects(). It soft-converts object columns to a better dtype where the values allow.
  5. Select columns by type. df.select_dtypes(include=["number", "bool"]) keeps matching columns; exclude= drops them. "number" expands to the NumPy numeric child types.

Worked example on survey-style data

import pandas as pddf = pd.DataFrame({    "id": ["001", "002", "003"],    "score": ["4", "5", "n/a"],    "wave": ["a", "b", "a"],})df["score"] = pd.to_numeric(df["score"], errors="coerce")  # float64: 4.0, 5.0, NaNdf["score"] = df["score"].astype("Int64")                  # nullable: 4, 5, <NA>df["wave"] = df["wave"].astype("category")

Run on pandas 3.0.5, all three columns load as str. The id column is deliberately left as text so that 001 keeps its zeros. After to_numeric with errors="coerce", score is float64 because NaN is a float; casting to the nullable Int64 restores integer values and stores the missing entry as <NA>.

Output and how to read it

Common dtypes and their aliases

Dtype String alias Typical research use (editorial guidance)
int64 / float64 "int64", "float64" Counts and measurements; the defaults for integers and floats regardless of platform.
Nullable integer "Int8" to "Int64", "UInt8" to "UInt64" Whole-number responses or counts that can be missing.
Nullable float "Float32", "Float64" Measurements with proper missing-value handling.
BooleanDtype "boolean" Yes/no flags that may be missing.
StringDtype "string" Identifiers and free text.
CategoricalDtype "category" Study arm, site, wave, coded responses.
datetime64[ns] "datetime64[ns]" Timestamps without a timezone.
DatetimeTZDtype "datetime64[ns, <tz>]" Timestamps with a timezone.
PeriodDtype / IntervalDtype "period[<freq>]", "interval" Reporting periods; binned ranges.
SparseDtype "Sparse" Mostly-empty indicator matrices.

Dtype names and aliases come from the pandas user guide; the right-hand column is editorial guidance, not a pandas rule.

Strings: object versus str

The pandas documentation says strings can be held in two ways, object dtype or StringDtype, and recommends StringDtype; object dtype should be avoided to the extent possible. In pandas 3.x string columns show dtype str, and select_dtypes(include=[str]) now selects them, where earlier code used include=[object]. Code written for pandas 2.x that selects text columns with [object] can therefore miss string columns after an upgrade.

Mixed values and defaults

pd.Series([1, 2, 3, 4, 5, 6.0]) is float64, while pd.Series([1, 2, 3, 6.0, "foo"]) is object, so one stray text value turns a numeric column into object. Upcasting follows NumPy rules, and to_numpy() returns the lowest common dtype across columns.

Troubleshooting

ValueError when calling astype

An invalid conversion raises. On pandas 3.0.5, pd.Series(["4", "n/a"]).astype("int64") raises ValueError: invalid literal for int() with base 10: 'n/a'. Use pd.to_numeric(..., errors="coerce") first, inspect the resulting NaN rows, then cast to Int64 if you need integers.

Integer column became float

An operation that introduces NaN upcasts integer columns to float; for instance df[df > 0] on an integer frame returns float64 columns. Use a nullable integer dtype (Int64) when missing values are expected. Handling the missing rows themselves is covered in dropna in pandas.

The assigned dtype did not stick with loc

The documentation warns that dft.loc[:, ["a", "b"]] = dft.loc[:, ["a", "b"]].astype(np.uint8) keeps the original int64 dtype, because loc fits values into the existing dtype, whereas dft[["a", "b"]] = ... overwrites the columns and their dtype.

Naive to timezone-aware

Since pandas 2.0.0, astype from a naive datetime to a timezone-aware one raises; use Series.dt.tz_localize() instead.

The copy argument

The copy argument of astype is deprecated and ignored since pandas 3.0.0, which uses Copy-on-Write.

Free alternatives

pandas is itself free and open-source. These related free pieces of the Python stack are covered elsewhere on this site:

Tool or task Guide
NumPy arrays (one dtype per array) NumPy sum, which shows how dtype affects results
Building a DataFrame from scratch Create a DataFrame in Python

FAQ

How do I check the dtype of a pandas column?

Use df.dtypes for all columns or df["col"].dtype for one.

How do I change a column’s dtype?

Use df["col"] = df["col"].astype("float64"), or df.astype({"col": "float64"}) for several columns at once. For text that may contain bad values, use pd.to_numeric with errors="coerce".

What does the object dtype mean?

It is the fallback for mixed or Python-object values, and historically for strings. The pandas documentation recommends StringDtype for text.

Should I keep ID codes as numbers?

This is editorial advice, not a pandas rule: store identifiers with leading zeros as strings, since they are labels rather than quantities.

Sources

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about pandas dtypes: Inspect, Convert and Choose Types

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →