如何将PySpark DataFrame中的字典列拆分为多行结构化数据
问题根因
你最开始读取JSON时将name、id字段指定为StringType,所以读入后是JSON格式字符串,不是可被explode处理的映射/数组类型;且你使用from_json时传入了固定结构的StructType,无法适配动态数量的键,因此解析结果为null。
解决步骤
用MapType作为解析schema,无需提前知晓内部键的数量,可自动适配任意数量的键值对,再通过explode拆分后按公共键关联即可。
场景1:还未读取JSON文件,直接指定正确schema读取
from pyspark.sql.types import StructType, StructField, MapType, StringType from pyspark.sql import functions as f # 定义schema时直接将name、id指定为Map类型,key和value都是字符串 read_schema = StructType([ StructField("name", MapType(StringType(), StringType()), True), StructField("id", MapType(StringType(), StringType()), True) ]) # 读取文件 spark_df = spark.read.schema(read_schema).json('path_to_json_file', multiLine=True)
场景2:已经将数据读为StringType,可二次转换为Map类型
map_schema = MapType(StringType(), StringType()) spark_df = spark_df \ .withColumn("name", f.from_json("name", map_schema)) \ .withColumn("id", f.from_json("id", map_schema))
拆分得到目标格式
# 分别拆分name、id字段,得到索引key和对应的值 name_split = spark_df.select(f.explode("name").alias("idx", "name")) id_split = spark_df.select(f.explode("id").alias("idx", "id")) # 按索引关联两个表,删除索引列即可得到目标结果 result_df = name_split.join(id_split, on="idx").drop("idx") result_df.show()
输出结果:
+-----+-----+ | name| id| +-----+-----+ |name1|00001| |name2|00002| |name3|00013| +-----+-----+
内容的提问来源于stack exchange,提问作者Nina
相关产品推荐
相关产品推荐

