You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PySpark中转换嵌套DataFrame的Schema结构

PySpark Nested DataFrame Schema Transformation Example

Got it, let's walk through a concrete, practical example to show how to convert a nested PySpark DataFrame from one schema to another. I'll start by defining a realistic source schema, a target schema we want to map to, and then the transformation code to make it happen.

Source Nested Schema

Let's use a common e-commerce-style nested structure with user details, nested orders, and nested line items inside each order:

from pyspark.sql.types import (
    StructType, StructField, StringType, IntegerType, ArrayType, DoubleType
)

source_schema = StructType([
    StructField("user_id", StringType(), nullable=False),
    StructField("user_name", StringType(), nullable=False),
    StructField("contact_info", StructType([
        StructField("email", StringType(), nullable=True),
        StructField("phone", StringType(), nullable=True)
    ])),
    StructField("orders", ArrayType(StructType([
        StructField("order_id", StringType(), nullable=False),
        StructField("order_date", StringType(), nullable=False),
        StructField("shipping_address", StructType([
            StructField("street", StringType(), nullable=False),
            StructField("city", StringType(), nullable=False)
        ])),
        StructField("line_items", ArrayType(StructType([
            StructField("product_id", StringType(), nullable=False),
            StructField("quantity", IntegerType(), nullable=False),
            StructField("unit_price", DoubleType(), nullable=False)
        ])))
    ])))
])

Sample source data snippet to visualize the structure:

{
"user_id": "U1001",
"user_name": "Jane Smith",
"contact_info": {"email": "jane@example.com", "phone": "555-1234"},
"orders": [
{
"order_id": "O2001",
"order_date": "2024-02-20",
"shipping_address": {"street": "123 Main St", "city": "New York"},
"line_items": [
{"product_id": "P3001", "quantity": 2, "unit_price": 19.99},
{"product_id": "P3002", "quantity": 1, "unit_price": 49.99}
]
}
]
}

Target Schema

Let's say we want to flatten the structure, move order and line item fields to the top level, and add a calculated line_item_total field (using the formula quantity * unit_price):

target_schema = StructType([
    StructField("user_id", StringType(), nullable=False),
    StructField("user_name", StringType(), nullable=False),
    StructField("user_email", StringType(), nullable=True),
    StructField("user_phone", StringType(), nullable=True),
    StructField("order_id", StringType(), nullable=False),
    StructField("order_date", StringType(), nullable=False),
    StructField("shipping_city", StringType(), nullable=False),
    StructField("product_id", StringType(), nullable=False),
    StructField("quantity", IntegerType(), nullable=False),
    StructField("unit_price", DoubleType(), nullable=False),
    StructField("line_item_total", DoubleType(), nullable=False)
])

Transformation Code

Here's how to convert the source DataFrame to match the target schema using PySpark's built-in functions:

from pyspark.sql import functions as F

# Assume `source_df` is your DataFrame loaded with the source_schema
transformed_df = (
    source_df
    # Flatten the contact_info struct first
    .withColumn("user_email", F.col("contact_info.email"))
    .withColumn("user_phone", F.col("contact_info.phone"))
    # Explode the orders array to get one row per order
    .withColumn("order", F.explode(F.col("orders")))
    # Explode line items to get one row per product in the order
    .withColumn("line_item", F.explode(F.col("order.line_items")))
    # Select and reshape all fields to match the target schema
    .select(
        "user_id",
        "user_name",
        "user_email",
        "user_phone",
        F.col("order.order_id"),
        F.col("order.order_date"),
        F.col("order.shipping_address.city").alias("shipping_city"),
        F.col("line_item.product_id"),
        F.col("line_item.quantity"),
        F.col("line_item.unit_price"),
        # Calculate derived field using the formula
        (F.col("line_item.quantity") * F.col("line_item.unit_price")).alias("line_item_total")
    )
)

# Verify the output schema matches the target
transformed_df.printSchema()

Key Tips for Schema Conversion:

  • Use F.explode() to flatten array fields into individual rows
  • Access nested struct fields with dot notation (e.g., contact_info.email)
  • Use alias() to rename fields to match the target schema's naming conventions
  • Calculate derived fields directly in the select clause using PySpark's arithmetic functions

内容的提问来源于stack exchange,提问作者jitendra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:27:11