PySpark如何将DataFrame的Map列拆分为键值两列并展开多行
Spark 展开Map类型列为多行键值列
问题说明
现有包含Map类型字段label的DataFrame,初始构造代码和数据如下:
sdf = spark.createDataFrame( [ (1, {'Kira':25,'Lilly':15}), (2, {'Tom':14}), ], ["id", "label"] )
初始数据预览:
+---+-------------------------+ |id |label | +---+-------------------------+ |1 |{Lilly -> 15, Kira -> 25}| |2 |{Tom -> 14} | +---+-------------------------+
需要将Map列的键提取为name列、值提取为age列,每个键值对拆为单独行,目标结果结构如下:
+---+-----+---+ |id |name |age| +---+-----+---+ |1 |Kira |25 | |1 |Lilly|15 | |2 |Tom |14 | +---+-----+---+
实现方案
直接使用Spark内置的explode表生成函数即可,无需自定义UDF,是性能最优的实现方式。explode传入Map类型列作为参数时,会自动遍历Map中所有键值对,将每个键值对拆分为独立数据行,默认生成key(对应Map键)、value(对应Map值)两列,直接通过alias重命名为目标列名name、age,同时保留原有的id列即可得到目标结果。
完整PySpark实现代码:
# 导入Spark内置函数 from pyspark.sql import functions as F # 展开Map列完成转换 result_sdf = sdf.select( "id", F.explode("label").alias("name", "age") ) # 打印验证结果 result_sdf.show()
若使用Scala API,逻辑完全一致,代码参考如下:
import org.apache.spark.sql.functions._ val resultSdf = sdf.select($"id", explode($"label").as(Seq("name", "age"))) resultSdf.show()
内容的提问来源于stack exchange,提问作者Rory
相关产品推荐
相关产品推荐

