PySpark中提取嵌套JSON各级数组为独立DataFrame的技术求助
Hey there! It sounds like you’ve already nailed handling top-level arrays like des_facet or media into separate DataFrames—nice work! The trick with second-level nested arrays (like media-metadata inside the media struct) is to first expand the parent array, then target the nested array within it, while holding onto a key to link everything back to your original records.
Let’s walk through a concrete example using your schema:
Step 1: Expand the Parent Array (media)
First, use explode_outer (this preserves rows even if media is null) to flatten the media array into individual struct rows. We’ll keep the original id field as a foreign key to tie all child records back to the main dataset:
from pyspark.sql.functions import explode_outer, col # Assume your main DataFrame is named `main_df` media_expanded_df = main_df.select( col("id").alias("article_id"), # Rename for clarity in the child DataFrame explode_outer(col("media")).alias("media_item") )
Step 2: Extract and Expand the Nested Array (media-metadata)
Now that each media_item is a separate row, we can target the nested media-metadata array inside it. We’ll again use explode_outer to split this array into individual rows, then extract the specific fields we need from the flattened structs:
media_metadata_df = media_expanded_df.select( col("article_id"), # Extract relevant fields from the parent media struct if needed col("media_item.approved_for_syndication"), col("media_item.caption"), # Expand the nested media-metadata array explode_outer(col("media_item.media-metadata")).alias("metadata") ).select( "article_id", "approved_for_syndication", "caption", # Pull fields from the flattened metadata struct col("metadata.format"), col("metadata.height"), col("metadata.url"), col("metadata.width") )
Step 3: Verify the Flattened Result
You can check the schema of your new media_metadata_df to confirm it’s fully flattened:
media_metadata_df.printSchema()
The output will look like this (no nested arrays remaining):
root |-- article_id: long (nullable = true) |-- approved_for_syndication: long (nullable = true) |-- caption: string (nullable = true) |-- format: string (nullable = true) |-- height: long (nullable = true) |-- url: string (nullable = true) |-- width: long (nullable = true)
General Pattern for Deeper Nested Arrays
This approach works for any level of nested arrays:
- Start with the top-level array, expand it, and retain a link key to the original data.
- For each subsequent nested array, expand it in the already flattened DataFrame, keeping the link key intact each time.
- Extract only the fields you need at each step to keep your child DataFrames focused and clean.
This way, you’ll end up with separate, fully flattened DataFrames for every array (both top-level and nested) that you can work with independently, while still being able to join back to the main dataset using the shared key (like article_id in our example).
内容的提问来源于stack exchange,提问作者Sreedev Nair

