Question

Convert Pandas DataFrame Columns to Float Types

pythonpandasdataframetypestype-conversion

Question

Given a list of lists containing text values, create a pandas DataFrame and convert the second and third columns to floating-point numbers.

import pandas as pd

table = [
    ["a", "1.2", "4.2"],
    ["b", "70", "0.03"],
    ["x", "5", "0"],
]

df = pd.DataFrame(table)

How can columns 2 and 3 be converted to float values? Can column types be specified while creating the DataFrame, or should the DataFrame be created first and then have its column dtypes changed? How can this be handled dynamically when there may be hundreds of columns, but every individual column contains values of one consistent type?

Short Answer

You will learn how pandas chooses DataFrame column types, how to explicitly convert columns with astype(), and how to safely detect and convert numeric-looking text with pd.to_numeric() when the schema is not known in advance.

Concept

A pandas DataFrame stores data in columns, and each column has a dtype (data type). Common dtypes include:

  • object or string for text
  • int64 for whole numbers
  • float64 for decimal numbers
  • bool for True and False
  • datetime64[ns] for dates and times

In the example, every value except those in the first column is written with quotes. That means Python creates them as strings:

"1.2"  # string
1.2    # float

Because the values are strings, pandas initially creates all three columns with an object dtype (or a string-like representation depending on pandas configuration). A value that looks numeric is still text until it is parsed or converted.

For columns that are known to be numeric, convert them explicitly. This prevents later calculations from behaving incorrectly. For example, adding two strings joins them instead of performing arithmetic:

"1.2" + "4.2"  # "1.24.2"

After conversion, pandas can calculate numeric results correctly:

1.2 + 4.2  # 5.4

Explicit conversion is usually best when you know the expected schema. Dynamic conversion is useful for imported or unknown data, but it must handle invalid values deliberately.

Mental Model

Think of each DataFrame column as a box with a label describing what it can hold.

  • A text box stores characters, even when they look like numbers.
  • A number box stores values that can be added, averaged, and compared numerically.

astype(float) tells pandas: “Move every item in this column into a floating-point number box.” If an item cannot be understood as a number, the move fails.

pd.to_numeric() is like a number-reading tool. It reads text such as "70" and "0.03" and turns it into numeric values. It also gives you options for deciding what should happen when it encounters text that is not numeric.

Take Quiz

Syntax and Examples

Use astype() when you know the target dtype and all values are valid for that dtype.

import pandas as pd

table = [
    ["a", "1.2", "4.2"],
    ["b", "70", "0.03"],
    ["x", "5", "0"],
]

df = pd.DataFrame(table, columns=["code", "amount", "rate"])

df[["amount", "rate"]] = df[["amount", "rate"]].astype(float)

print(df)
print(df.dtypes)

Output:

  code  amount  rate
0    a     1.2  4.20
1    b    70.0  0.03
2    x     5.0  0.00

code       object
amount    float64
rate      float64
dtype: object

Columns can also be selected by position. pandas uses zero-based positions, so the second and third columns have positions 1 and 2:

df.iloc[:, [1, 2]] = df.iloc[:, [1, 2]].astype(float)

For a single column:

df["amount"] = df["amount"].astype(float)

If the data may contain invalid numeric text, use pd.to_numeric() instead:

df["amount"] = pd.to_numeric(df["amount"], errors="coerce")

With errors="coerce", invalid values become missing values (NaN) instead of raising an exception.

Step by Step Execution

Consider this small example:

import pandas as pd

df = pd.DataFrame({
    "product": ["pen", "book"],
    "price": ["1.50", "12.00"]
})

print(df["price"].dtype)

df["price"] = df["price"].astype(float)

print(df["price"].dtype)
print(df["price"].mean())

Step by step:

  1. pd.DataFrame(...) creates a price column from "1.50" and "12.00".
  2. Quotes make both values strings, so df["price"].dtype is initially object.
  3. astype(float) parses each string as a floating-point value.
  4. The converted values are assigned back to df["price"]. Assignment is important because conversion methods return a new Series or DataFrame.
  5. The dtype is now float64.
  6. .mean() can now calculate (1.5 + 12.0) / 2, producing 6.75.

If price contained "unknown", astype(float) would raise a ValueError. Use pd.to_numeric(..., errors="coerce") when invalid values should become missing data instead.

Real World Use Cases

Column conversion is common whenever data arrives as text.

  • CSV imports: Prices, quantities, and percentages often arrive as strings.
  • API responses: JSON fields may contain numeric values encoded as strings, such as "total": "49.99".
  • Spreadsheets: User-entered values may need conversion before calculating totals or averages.
  • Data cleaning: A column may contain values such as "12", "15", and "not available"; numeric parsing can turn the invalid value into missing data for later review.
  • Database loading: Convert data to expected dtypes before inserting records into typed database columns.
  • Reporting: Numeric dtypes are required for aggregations such as sum(), mean(), and groupby() calculations.
Take Quiz

Real Codebase Usage

In real projects, developers usually define an expected schema when it is known rather than relying entirely on automatic inference.

Convert known columns together

numeric_columns = ["amount", "rate", "discount"]
df[numeric_columns] = df[numeric_columns].apply(pd.to_numeric, errors="raise")

errors="raise" is useful in data pipelines where invalid input should stop processing immediately.

Convert unknown columns cautiously

When columns may or may not be numeric, attempt conversion one column at a time:

for column in df.columns:
    try:
        df[column] = pd.to_numeric(df[column], errors="raise")
    except (ValueError, TypeError):
        pass

This converts columns that are entirely numeric-looking and leaves text columns unchanged. It fits the condition that each column contains one consistent type.

Keep invalid values as missing data

For files that can contain blanks or bad values, preserve the column as numeric and mark problematic entries as missing:

df["amount"] = pd.to_numeric(df["amount"], errors="coerce")

invalid_rows = df[df["amount"].isna()]

This pattern supports validation: process valid values while separately logging or fixing invalid rows.

Prefer schema-aware import when reading files

When loading a CSV and the schema is known, set types at the boundary:

df = pd.read_csv(
    "sales.csv",
    dtype={"product_code": "string"},
    converters={
        "amount": float,
        "rate": float,
    },
)

For a DataFrame built directly from a list, dtype= applies one dtype broadly; it cannot conveniently assign a different dtype to each individual column. Creating the DataFrame and converting selected columns is normally clearer.

Common Mistakes

Forgetting to assign the converted result

Most conversion operations do not modify the original column automatically.

# Incorrect: df is unchanged
df["amount"].astype(float)
# Correct
df["amount"] = df["amount"].astype(float)

Converting the text identifier column

The first column contains codes such as "a", "b", and "x". Trying to convert it to float fails.

# Raises ValueError
df = df.astype(float)

Convert only appropriate columns instead.

df[["amount", "rate"]] = df[["amount", "rate"]].astype(float)

Confusing column labels and positions

Without specified column names, pandas labels the columns 0, 1, and 2. The second column is label 1, not 2.

# With default labels, this selects columns labeled 1 and 2
df[[1, 2]] = df[[1, 2]].astype(float)

For readability, assign meaningful column names when creating the DataFrame.

Using errors="ignore" without checking results

df["amount"] = pd.to_numeric(df["amount"], errors="ignore")

If any value cannot be converted, errors="ignore" can leave the whole Series unchanged. Prefer errors="raise" for strict validation or errors="coerce" to identify invalid entries as NaN.

Assuming pandas converts numeric-looking strings automatically

Pandas can infer types when Python values are actual numbers, but strings remain strings:

pd.DataFrame([["1.2"], ["5"]]).dtypes  # object
pd.DataFrame([[1.2], [5.0]]).dtypes      # float64

Comparisons

Tool or approachBest useInvalid valuesResult
astype(float)Every value is known to be validRaises an errorExactly the requested dtype
pd.to_numeric(..., errors="raise")Strict validation of numeric textRaises an errorNumeric dtype when possible
pd.to_numeric(..., errors="coerce")Cleaning imperfect dataBecomes NaNNumeric dtype with missing values
pd.to_numeric(..., errors="ignore")Rarely recommendedLeaves unconvertible input unchangedMay remain text
convert_dtypes()Improving nullable pandas dtypesDoes not reliably parse numeric stringsUses pandas extension dtypes

astype() and pd.to_numeric() have different strengths:

# Request one exact dtype
df["amount"] = df["amount"].astype("float64")

# Parse numeric text and choose an error policy
df["amount"] = pd.to_numeric(df["amount"], errors="coerce")

convert_dtypes() is not a replacement for numeric parsing. It can improve inferred dtypes in an existing DataFrame, but text values such as "1.2" should be explicitly parsed with pd.to_numeric().

Take Quiz

Cheat Sheet

# Convert named columns to floats
df[["amount", "rate"]] = df[["amount", "rate"]].astype(float)

# Convert columns by zero-based position
df.iloc[:, [1, 2]] = df.iloc[:, [1, 2]].astype(float)

# Strict numeric parsing
df["amount"] = pd.to_numeric(df["amount"], errors="raise")

# Bad values become NaN
df["amount"] = pd.to_numeric(df["amount"], errors="coerce")

# Try to convert every fully numeric column
for col in df.columns:
    try:
        df[col] = pd.to_numeric(df[col], errors="raise")
    except (ValueError, TypeError):
        pass

# Inspect dtypes
print(df.dtypes)

Key rules:

  • Quoted numbers are strings, not numeric values.
  • pandas column positions start at 0.
  • Assign conversion results back to the DataFrame.
  • Use astype() for trusted data and to_numeric() for parsing and validation.
  • float columns can represent missing numeric values as NaN.

FAQ

How do I convert multiple pandas columns to float?

Select the columns and assign the converted result back:

df[["amount", "rate"]] = df[["amount", "rate"]].astype(float)

Why are numeric values stored as object in my DataFrame?

They were likely supplied as quoted strings, such as "70" or "0.03". pandas preserves them as text until you convert them.

Can I set a different dtype for each column in pd.DataFrame()?

Not conveniently with the dtype= argument when building directly from a list of lists. dtype= is appropriate when the DataFrame should use one common dtype. Create the DataFrame, then convert selected columns, or provide actual Python numeric values in the input.

Should I use astype(float) or pd.to_numeric()?

Use astype(float) when all values are guaranteed to be valid floats. Use pd.to_numeric() when parsing text data and you need control over invalid values.

How do I find columns that can be converted to numbers automatically?

Try pd.to_numeric(column, errors="raise") for each column and keep the conversion only when it succeeds. This works well when each column has a consistent type.

What happens when pd.to_numeric(errors="coerce") finds invalid text?

It replaces invalid values with NaN, allowing the rest of the column to remain numeric.

Are the second and third columns numbered 2 and 3 in pandas?

Positions are zero-based, so they are positions 1 and 2. If default labels are used, their labels are also 1 and 2.

Take Quiz

Mini Project

Description

Build a small order-data cleaning function. The input resembles data from a CSV export: product identifiers are text, while quantity and unit price are numeric values stored as strings. The function should convert valid numeric columns and calculate a line total.

Goal

Create a cleaned DataFrame with numeric quantity, unit_price, and line_total columns while preserving product codes as text.

Requirements

Create a DataFrame from the provided order rows. Convert the quantity and unit_price columns to numeric values. Treat invalid numeric values as missing rather than crashing. Add a line_total column calculated from quantity times unit price. Print the cleaned DataFrame and its dtypes.

Take Quiz

Keep learning

Related questions

View more