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

如何使用PySpark炸开存储为String类型的DataFrame数组列?

问题原因及解决方案

你的special_values列字符串不是标准JSON格式,这是导致from_json解析失败、最终得到空DataFrame的核心原因:

  • 标准JSON要求键名必须用双引号包裹,比如{"name":"address"},但你的字符串里是{name=address},键名没有引号
  • 标准JSON用冒号:分隔键值对,你的用的是等号=
  • 字符串类型的取值也没有双引号,比如value=some address应该是"value":"some address"

from_json只能解析标准JSON格式的字符串,所以解析后special_value列全是null,后续inline自然没有数据输出。


解决方案

先通过字符串替换把非标准格式转换成标准JSON,再进行解析和炸开。具体代码如下:

from pyspark.sql import functions as F
from pyspark.sql.types import ArrayType, StructType, StructField, StringType

# 定义目标Schema
user_schema = ArrayType(
    StructType([
        StructField("name", StringType(), True),
        StructField("value", StringType(), True)
    ])
)

df2 = (df1
       # 替换键名后的等号为冒号,并给键名加双引号
       .withColumn("json_str", F.regexp_replace("special_values", r"(\w+)=", r'"\1":'))
       # 给无引号的字符串值加上双引号
       .withColumn("json_str", F.regexp_replace("json_str", r":([^,\}]+)", r':"$1"'))
       # 解析成数组结构
       .withColumn("special_value", F.from_json("json_str", user_schema))
       # 炸开数组并保留原有列,重命名避免字段冲突
       .selectExpr("name", "last_name", "inline(special_value)")
       .withColumnRenamed("name", "attr_name")
       )

df2.show()

执行后会得到预期结果:

+----+---------+---------+-------------+
|name|last_name|attr_name|        value|
+----+---------+---------+-------------+
|   A|        B|  address| some address|
|   A|        B|     city|          Chd|
|   A|        B| zip_code|       160036|
|   X|        Y|  address| some address|
|   X|        Y|     city|       Dallas|
|   X|        Y| zip_code|        02431|
+----+---------+---------+-------------+

额外优化建议

如果是从你提供的源JSON数据加载DataFrame,建议直接指定完整Schema加载,避免把数组转成String类型:

# 定义完整Schema
full_schema = StructType([
    StructField("name", StringType(), True),
    StructField("last_name", StringType(), True),
    StructField("special_values", user_schema, True)
])

# 直接加载JSON数据(假设数据存于文件)
df1 = spark.read.schema(full_schema).json("path/to/your/data.json")

# 直接炸开数组即可
df2 = df1.selectExpr("name", "last_name", "inline(special_values)")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 14:43:11