Skip to content
Everyone knows 3 min read · Types

cast and schemas

Change column types safely, read a schema, and avoid the silent nulls bad casts produce.

You will learn

  • How to change a column's type with cast
  • What happens to values that cannot be converted
  • How to read a DataFrame's schema and types
  • Why decimals, not doubles, belong in money columns

Read first

Comfortable with these? Read on.

TL;DR F.col("x").cast("int") converts a column. A value that cannot be converted becomes null without any error (in Spark 4.0 with ANSI mode on, it raises an error instead, and try_cast gives you the null). Always count the nulls a cast produced.

What it does

Data read from CSV, JSON or an API often arrives as strings. cast converts a column to another type so you can do maths, compare dates and sort numbers numerically ("10" sorts before "9" as a string).

Type stringSpark typeExample
"int" / "bigint"IntegerType / LongType"42" → 42
"double"DoubleType"19.99" → 19.99
"decimal(10,2)"DecimalType(10, 2)"19.99" → 19.99 exactly
"boolean"BooleanType"true" → true, "yes" → null
"date"DateType"2025-03-01" → 2025-03-01
"timestamp"TimestampType"2025-03-01 09:15:00"
"string"StringType42 → "42"

Run the example

PySparkSpark SQL
from pyspark.sql import functions as F
result = raw_orders.select(
    F.col("order_id").cast("int").alias("order_id"),
    F.col("amount").cast("double").alias("amount"),
    F.col("qty").cast("int").alias("qty"),
    F.col("paid").cast("boolean").alias("paid"),
)
SELECT CAST(order_id AS INT)   AS order_id,
       CAST(amount AS DOUBLE)  AS amount,
       CAST(qty AS INT)        AS qty,
       CAST(paid AS BOOLEAN)   AS paid
FROM raw_orders

Switch to PySpark to edit and run this example in your browser.

Input

columnraw value
amount"abc"
qty"two"
paid"yes"

Output

columnafter cast
amountnull
qtynull
paidnull

What happened to each bad value

No error, no warning: three values quietly became null. In the running example this is classic Spark behaviour, which the in-browser engine follows.

Spark 4.0: ANSI mode and try_cast

Spark 4.0 turns on spark.sql.ansi.enabled by default. With it, CAST('abc' AS INT) fails the query with a CAST_INVALID_INPUT error instead of returning null. When bad values are expected, say so explicitly with try_cast, which returns null:

PySparkSpark SQL · Explicit about bad values
clean = raw_orders.select(F.col("amount").try_cast("double").alias("amount"))   # Spark 4.0+
# Spark 3.x: F.expr("try_cast(amount AS DOUBLE)")
SELECT try_cast(amount AS DOUBLE) AS amount FROM raw_orders

Counting what a cast lost

A value that was present before the cast and null after it is a conversion failure. Count those before you trust the result:

PySparkSpark SQL · Audit a cast
bad = raw_orders.filter(F.col("amount").isNotNull() & F.col("amount").cast("double").isNull())
print(bad.count())   # 1 row: "abc"
SELECT * FROM raw_orders
WHERE amount IS NOT NULL AND CAST(amount AS DOUBLE) IS NULL

Reading a schema

  • df.printSchema() prints the tree of column names, types and nullability.
  • df.dtypes returns a list such as [("order_id", "int"), ("amount", "double")].
  • df.schema returns the StructType object; df.schema["amount"].dataType gives one column's type.
  • To cast many columns at once, build one select: df.select([F.col(c).cast("double") for c in cols]).

double vs decimal for money

A double is a binary fraction: 0.1 + 0.2 is 0.30000000000000004. Summing millions of prices as doubles drifts by cents. decimal(p, s) stores exact digits: p total digits, s after the point. Use decimal(18,2) or similar for money. Values that do not fit the precision become null (or an error under ANSI mode), so leave room for totals.

Watch out: casting a double to int truncates toward zero: -2.7 becomes -2. Round first with F.round if you want rounding.

Common mistakes

Not checking for nulls after a cast

Bad values turn into null silently, and counts and sums are quietly wrong. Audit with "not null before, null after".

Money as double

Rounding errors add up. Use decimal.

Sorting numbers stored as strings

"10" sorts before "9". Cast before orderBy.

Expecting "yes"/"no" to cast to boolean

Only true/false, t/f, y/n, 1/0 style values convert; map the rest with when/otherwise.

Key takeaways

  • cast converts types; failures become null (or errors in ANSI mode).
  • try_cast makes "bad values become null" explicit.
  • Audit casts: not null before and null after means lost data.
  • Use decimal for money and cast before sorting numbers.

Check yourself

3 questions

1. In classic (non-ANSI) Spark, what is CAST('abc' AS INT)?

Show the answer

null. Invalid input becomes null without an error.

2. Which function returns null for bad input even when ANSI mode is on?

Show the answer

try_cast. try_cast is the explicit "null on failure" cast.

3. Which type should store prices?

Show the answer

decimal(18,2). Decimals store exact digits; doubles accumulate binary rounding errors.

Keep going

Up next · lesson 6 of 35 · 3 min read
String functions
concat vs concat_ws, substring, split, trim and padding, with the null traps in each.

Related lessons

Previous: withColumn

Primary sources: Column.cast · Data types · ANSI compliance