Spark合并多列Map类型字段 按键对齐输出两列对应值
Spark 合并多Map列按公共键对齐的实现方案
核心实现逻辑
- 取两个Map列的所有键的并集,生成包含全量唯一键的数组
- 炸开该数组得到每个键对应的独立行
- 分别从两个原Map列中读取当前键对应的取值,不存在的自动返回null
代码实现(Spark 2.4+ 推荐写法)
Scala DataFrame API 示例
import org.apache.spark.sql.functions._ val resultDF = df // 取两个Map列的键的并集,得到全量唯一键数组 .withColumn("all_keys", array_union(map_keys(col("mapCol1")), map_keys(col("mapCol2")))) // 炸开键数组生成每行对应一个键 .withColumn("Key 1&2", explode(col("all_keys"))) // 分别读取两个Map中对应键的取值 .withColumn("mapCol1_value", col("mapCol1").getItem(col("Key 1&2"))) .withColumn("mapCol2_value", col("mapCol2").getItem(col("Key 1&2"))) // 筛选需要的输出列 .select("ID", "Key 1&2", "mapCol1_value", "mapCol2_value")
Spark SQL 示例
SELECT ID, key AS `Key 1&2`, mapCol1[key] AS mapCol1_value, mapCol2[key] AS mapCol2_value FROM original_table LATERAL VIEW EXPLODE(ARRAY_UNION(map_keys(mapCol1), map_keys(mapCol2))) t AS key
低版本Spark兼容实现(2.4以下)
如果使用的Spark版本不支持array_union和map_keys函数,可以通过分别炸开两个Map列后做全外连接实现:
import org.apache.spark.sql.functions._ // 分别炸开两个Map列生成独立数据集 val dfMap1 = df.select("ID", explode(col("mapCol1")).toDF("key", "mapCol1_value")) val dfMap2 = df.select("ID", explode(col("mapCol2")).toDF("key", "mapCol2_value")) // 按ID和键做全外连接合并结果 val resultDF = dfMap1 .join(dfMap2, Seq("ID", "key"), "full_outer") .withColumnRenamed("key", "Key 1&2") .orderBy("ID", "Key 1&2")
内容的提问来源于stack exchange,提问作者eureka
相关产品推荐
相关产品推荐

