cast and schemas
Change column types safely, read a schema, and avoid the silent nulls bad casts produce.
On this page
Show code in
Every code block on the page follows this.
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
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 string | Spark type | Example |
|---|---|---|
| "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" | StringType | 42 → "42" |
Run the example
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
| column | raw value |
|---|---|
| amount | "abc" |
| qty | "two" |
| paid | "yes" |
Output
| column | after cast |
|---|---|
| amount | null |
| qty | null |
| paid | null |
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:
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:
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.dtypesreturns a list such as[("order_id", "int"), ("amount", "double")].df.schemareturns theStructTypeobject;df.schema["amount"].dataTypegives 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.
-2.7 becomes -2. Round first with F.round if you want rounding.Common mistakes
Not checking for nulls after a cast
Money as double
Sorting numbers stored as strings
Expecting "yes"/"no" to cast to boolean
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 questions1. 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 readString functions
concat vs concat_ws, substring, split, trim and padding, with the null traps in each.
Related lessons
Reading and writing dataSpark internals · 3 min read
ANSI mode by defaultPySpark functions · 3 min read
fillna / dropna
Previous: withColumn
Primary sources: Column.cast · Data types · ANSI compliance