Skip to content
LakeBench
ProblemsCommunityPricing
Sign inStart practicing
Back
  1. Home
  2. Interview prep
  3. Flatten nested JSON

PySpark · DataFrame API in Practice

Flatten nested JSON

Mediumpyspark-75
jsonnested-dataexplodestructarray

Question

How do you flatten a deeply nested JSON structure in PySpark?

Solution

Flatten nested JSON by selecting struct fields with dot notation and exploding arrays into rows. Do it step by step, and watch the row count as you go.

Example structure

{ "order_id": 1,
  "customer": { "id": 7, "address": { "city": "Pune" } },
  "items": [ {"sku": "A", "qty": 2}, {"sku": "B", "qty": 1} ] }

Structs: dot notation

flat = df.select(
    "order_id",
    F.col("customer.id").alias("customer_id"),
    F.col("customer.address.city").alias("city"),
    "items",
)

You can also expand every field of a struct at once with select("customer.*").

Arrays: explode

items = flat.select("order_id", "customer_id", "city", F.explode("items").alias("item"))
items = items.select("order_id", "customer_id", "city", "item.sku", "item.qty")

explode makes one row per element. The order with two items becomes two rows, and the order-level columns repeat. Use explode_outer if rows with an empty or NULL array must stay, with NULL in the item columns. inline("items") expands an array of structs straight into columns.

Unknown depth

If the structure varies, write a small recursive function over df.schema: for each field, if it is a StructType select its children with a prefix, and if it is an ArrayType of structs explode it and continue until no complex types remain. Keep the aliases unique, for example customer_address_city.

def flatten_structs(df):
    cols = []
    for f in df.schema.fields:
        if isinstance(f.dataType, StructType):
            cols += [F.col(f"{f.name}.{c.name}").alias(f"{f.name}_{c.name}") for c in f.dataType.fields]
        else:
            cols.append(F.col(f.name))
    return df.select(cols)

Call it repeatedly until no struct column remains.

Watch for row multiplication

If you explode two independent arrays in the same table, such as items and payments, you get a cross product: 3 items times 2 payments gives 6 rows per order. Explode each array in its own DataFrame and keep order_id as the link. Also remember that order-level amounts repeat after an explode, so summing them double counts.

🎯 Put this concept into practice

Solidify this answer with real hands-on interview drills in the browser studio.

Open related drill →
PreviousNext