Spark 2.3(Scala 2.11.8)中将Map键转换为独立列的方法
解决方案(Spark 2.3 + Scala 2.11.8)
针对你提供的DataFrame,需要将Desc_map列中的字符串格式键值对解析为独立列,具体步骤如下:
1. 定义解析字符串为Map的UDF
由于Desc_map是自定义格式的键值对字符串(非标准JSON),先通过UDF将其转换为Spark的Map类型:
import org.apache.spark.sql.functions._ val parseDescMap = udf((desc: String) => { desc.split(", ") .map(_.trim) .flatMap { kvStr => kvStr.split(" -> ") match { case Array(keyPart, valuePart) => // 去除键和值两端的引号 val cleanKey = keyPart.replaceAll("^\"|\"$", "") val cleanValue = valuePart.replaceAll("^\"|\"$", "") Some(cleanKey -> cleanValue) case _ => None // 兼容格式异常的行 } }.toMap })
2. 生成带解析后Map列的DataFrame
用上述UDF处理原表的Desc_map列:
val dfWithMap = yourOriginalDF.withColumn("parsed_map", parseDescMap($"Desc_map"))
3. 动态提取所有键并生成对应列
考虑到Desc_map中的键可能不固定(如示例中的....),先获取所有唯一键,再动态生成列:
// 获取所有唯一的键 val allKeys = dfWithMap.select(explode(map_keys($"parsed_map"))) .distinct() .as[String] .collect() // 遍历键,从Map中提取值作为新列 val finalDF = allKeys.foldLeft(dfWithMap) { (tempDF, key) => tempDF.withColumn(key, $"parsed_map".getItem(key)) } // 移除临时列和原Desc_map列 .drop("Desc_map", "parsed_map")
4. 查看结果
执行finalDF.show()即可得到你期望的宽表结构。
内容的提问来源于stack exchange,提问作者BHC
相关产品推荐
相关产品推荐

