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

如何在Apache Spark中将JSON文件转换为规则表格型DataFrame

问题根因说明

你给出的示例JSON本身没有嵌套结构,当前DataFrame不符合预期的核心问题是读取格式配置错误:你使用了csv格式读取JSON数据源,导致整行JSON被识别为单个字符串列,无法解析为结构化表格。

正确实现代码

方案1:直接读取JSON生成扁平结构(适配你给出的无嵌套JSON场景)

# 1. 读取JSON数据源,自动解析为结构化DataFrame
df = (spark.read 
      .format("json") \
      .schema(mySchema) \ # 如果提前定义了对应JSON结构的schema可以保留,也可以去掉让Spark自动推断
      .load(dataPath)    
     )

# 2. 直接导出为CSV格式
df.write \
  .format("csv") \
  .option("header", "true") \ # 导出CSV带表头
  .mode("overwrite") \
  .save("你的CSV导出路径")

方案2:通用嵌套JSON扁平化方法(适配真·嵌套JSON场景)

如果你后续遇到带嵌套字段的JSON,可以用下面的递归方法自动扁平化所有层级的嵌套结构:

from pyspark.sql.functions import col, explode_outer
from pyspark.sql.types import StructType, ArrayType

def flatten_df(nested_df):
    stack = [((), nested_df)]
    columns = []

    while len(stack) > 0:
        parents, df = stack.pop()
        for col_name, col_type in df.dtypes:
            if col_type.startswith("struct"):
                # 处理结构体嵌套
                projected = df.select(col(f"{col_name}.*"))
                stack.append((parents + (col_name,), projected))
            elif col_type.startswith("array"):
                # 处理数组类型嵌套,先炸开数组再继续处理
                exploded_df = df.withColumn(col_name, explode_outer(col(col_name)))
                stack.append((parents, exploded_df))
            else:
                # 扁平字段直接保留,嵌套层级用下划线拼接字段名
                flat_col_name = "_".join(parents + (col_name,))
                columns.append(col(f"{col_name}").alias(flat_col_name))
    
    return nested_df.select(columns)

# 调用方法生成完全扁平的DataFrame
flat_df = flatten_df(df)

# 导出为CSV
flat_df.write \
  .format("csv") \
  .option("header", "true") \
  .mode("overwrite") \
  .save("你的CSV导出路径")
效果验证

你给出的示例JSON运行方案1后,会直接生成5列的结构化表格,字段分别为constructorId、constructorRef、name、nationality、url,完全符合CSV导出要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 02:36:00