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

如何使用PySpark解析非标准结构的JSON文件?

PySpark解析动态键JSON数据的问题与解决

问题场景

给定如下格式的JSON文件:

{
  "42": {"name": "MeowBark", "id": 42, "category": "pet store"},
  "67": {"name": "Chef's Kiss", "id": 67, "category": "restaurant"}
}

使用以下PySpark代码读取:

stores = spark.read.json(stores, multiLine=True).cache()

得到的DataFrame不符合预期,结构如下:

key1key2
{MeowBark, true, pet store}{Chef's Kiss, false, restaurant}

需要仅用PySpark操作实现正确解析,避免依赖Pandas的转置方法。

问题原因

原JSON的顶层是动态数字键(如42、67),Spark默认会将每个顶层键解析为一个DataFrame列,导致生成key1、key2这类动态列,且列内的结构体未被展开为单独字段。

解决方法

核心思路是将动态键的结构转换为Map类型,再通过explode将Map拆分为多行,最后展开结构体字段。以下提供两种可行方案:

方案一:基于已读取的列转换为Map

# 1. 读取原始JSON
stores_df = spark.read.json("path/to/your/file.json", multiLine=True)

# 2. 将所有列转换为Map(键为列名,值为对应结构体)
from pyspark.sql.functions import create_map, lit, explode, chain

cols = stores_df.columns
map_col = create_map(list(chain(*[(lit(c), stores_df[c]) for c in cols])))

# 3. 拆分Map为行,得到store_id和store_info两列
exploded_df = stores_df.select(explode(map_col).alias("store_id", "store_info"))

# 4. 展开结构体字段为单独列
final_df = exploded_df.select(
    "store_id",
    "store_info.name",
    "store_info.id",
    "store_info.category"
)

final_df.show()

方案二:直接读取文本并解析为Map

这种方法跳过Spark自动拆分列的步骤,直接解析整个JSON为Map:

# 1. 读取整个JSON文件为单一文本列
text_df = spark.read.text("path/to/your/file.json", wholetext=True)

# 2. 定义结构体和Map类型
from pyspark.sql.functions import from_json
from pyspark.sql.types import MapType, StructType, StructField, StringType, IntegerType

store_struct = StructType([
    StructField("name", StringType()),
    StructField("id", IntegerType()),
    StructField("category", StringType())
])
map_type = MapType(StringType(), store_struct)

# 3. 解析文本为Map结构
parsed_df = text_df.select(from_json("value", map_type).alias("stores"))

# 4. 拆分Map为行并展开字段
exploded_df = parsed_df.select(explode("stores").alias("store_id", "store_info"))
final_df = exploded_df.select(
    "store_id",
    "store_info.name",
    "store_info.id",
    "store_info.category"
)

final_df.show()

执行后会得到预期的结构化DataFrame:

store_idnameidcategory
42MeowBark42pet store
67Chef's Kiss67restaurant

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 19:07:56