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

如何将Spark DataFrame的JSON列嵌套对象转为对象数组

Spark DataFrame嵌套JSON对象转数组的实现方案

需求说明

现有仅含TEST列的Spark DataFrame,列中JSON结构如下:

{
"TAXES": {
"TAX":
{
"TAXFREEFLAG": 0,
"TAXINCLUDEDFLAG": 1,
"TAXPERCENT": 5.5,
"TAXTYPE": 49,
"TICKETTAXABLEAMOUNT": 6.14,
"TICKETTAXAMOUNT": 0.34,
"TICKETTAXID": 1
}
}
}

需要将TAX字段从单个对象转换为包含该对象的数组,最终JSON结构如下:

{
"TAXES": {
"TAX": [
{
"TAXFREEFLAG": 0,
"TAXINCLUDEDFLAG": 1,
"TAXPERCENT": 5.5,
"TAXTYPE": 49,
"TICKETTAXABLEAMOUNT": 6.14,
"TICKETTAXAMOUNT": 0.34,
"TICKETTAXID": 1
}
]
}
}


方案一:Schema解析法(推荐)

通过定义JSON结构Schema,解析后重构数组字段再转回JSON格式,稳定性高,适配字段变化场景。

PySpark 实现代码

from pyspark.sql import functions as F
from pyspark.sql.types import StructType, StructField, IntegerType, DoubleType

# 定义TAX字段的Schema
tax_schema = StructType([
    StructField("TAXFREEFLAG", IntegerType()),
    StructField("TAXINCLUDEDFLAG", IntegerType()),
    StructField("TAXPERCENT", DoubleType()),
    StructField("TAXTYPE", IntegerType()),
    StructField("TICKETTAXABLEAMOUNT", DoubleType()),
    StructField("TICKETTAXAMOUNT", DoubleType()),
    StructField("TICKETTAXID", IntegerType())
])

# 定义TAXES字段的Schema
taxes_schema = StructType([StructField("TAX", tax_schema)])

# 定义根级Schema
root_schema = StructType([StructField("TAXES", taxes_schema)])

# 解析TEST列的JSON结构
df_parsed = df.withColumn("parsed_json", F.from_json(F.col("TEST"), root_schema))

# 将单个TAX对象包装为数组
df_with_array = df_parsed.withColumn(
    "tax_array",
    F.array(F.col("parsed_json.TAXES.TAX"))
)

# 重构JSON结构并转回字符串格式
df_result = df_with_array.withColumn(
    "TEST",
    F.to_json(
        F.struct(
            F.struct(F.col("tax_array").alias("TAX")).alias("TAXES")
        )
    )
).drop("parsed_json", "tax_array")

# 查看结果
df_result.show(truncate=False)

Scala 实现代码

import org.apache.spark.sql.functions._
import org.apache.spark.sql.types._

// 定义TAX字段的Schema
val taxSchema = StructType(Seq(
  StructField("TAXFREEFLAG", IntegerType),
  StructField("TAXINCLUDEDFLAG", IntegerType),
  StructField("TAXPERCENT", DoubleType),
  StructField("TAXTYPE", IntegerType),
  StructField("TICKETTAXABLEAMOUNT", DoubleType),
  StructField("TICKETTAXAMOUNT", DoubleType),
  StructField("TICKETTAXID", IntegerType)
))

// 定义TAXES字段的Schema
val taxesSchema = StructType(Seq(StructField("TAX", taxSchema)))

// 定义根级Schema
val rootSchema = StructType(Seq(StructField("TAXES", taxesSchema)))

// 解析TEST列的JSON结构
val dfParsed = df.withColumn("parsedJson", from_json(col("TEST"), rootSchema))

// 将单个TAX对象包装为数组
val dfWithArray = dfParsed.withColumn(
  "taxArray",
  array(col("parsedJson.TAXES.TAX"))
)

// 重构JSON结构并转回字符串格式
val dfResult = dfWithArray.withColumn(
  "TEST",
  to_json(
    struct(
      struct(col("taxArray").alias("TAX")).alias("TAXES")
    )
  )
).drop("parsedJson", "taxArray")

// 查看结果
dfResult.show(false)

方案二:字符串拼接法(快速实现)

如果确认原始JSON结构固定、无特殊字符干扰,可直接通过字符串拼接快速实现,缺点是容错性低。

PySpark 实现代码

from pyspark.sql import functions as F

df_result = df.withColumn(
    "TEST",
    F.concat(
        F.lit('{"TAXES": {"TAX": ['),
        F.get_json_object(F.col("TEST"), "$.TAXES.TAX"),
        F.lit(']}}')
    )
)

df_result.show(truncate=False)

Scala 实现代码

import org.apache.spark.sql.functions._

val dfResult = df.withColumn(
  "TEST",
  concat(
    lit("{\"TAXES\": {\"TAX\": ["),
    get_json_object(col("TEST"), "$.TAXES.TAX"),
    lit("]}}")
  )
)

dfResult.show(false)

内容的提问来源于stack exchange,提问作者Asri Med Amin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 23:07:39