Spark Scala:从数组列生成DataFrame多列的技术实现问询
解决方案:Spark Scala 从数组列生成多列
这里有一个完整的Spark Scala实现方案,完美匹配你想要的转换效果:
核心思路
先将数组格式的details列展开为多行,拆分出独立的键值对,再通过**透视(pivot)**操作将行转列为目标格式,缺失的字段会自动填充null。
完整代码示例
import org.apache.spark.sql.functions._ import org.apache.spark.sql.types.IntegerType import spark.implicits._ // 1. 模拟你的输入DataFrame val inputDF = Seq( ("Toyota", Seq(Seq("year", "2000"), Seq("price", "20000"))), ("Audi", Seq(Seq("mpg", "22"))) ).toDF("Car name", "details") // 2. 展开details数组,拆分每个键值对为key和value列 val explodedDF = inputDF .select($"Car name", explode($"details").alias("kv_pair")) // 将数组拆分为多行,每个键值对单独成行 .select( $"Car name", $"kv_pair"(0).alias("attribute"), // 提取属性名(如year/price/mpg) $"kv_pair"(1).cast(IntegerType).alias("value") // 提取属性值并转为整数类型,不需要转类型可去掉cast ) // 3. 透视转换:将attribute行转为列,聚合取对应的值 val resultDF = explodedDF .groupBy($"Car name") .pivot("attribute") // 指定要转为列名的字段 .agg(first($"value")) // 取每个车辆对应属性的第一个值(因为每个属性唯一,用first/max都可以) // 查看最终结果 resultDF.show()
代码细节解释
explode函数:把details列的数组元素拆分成独立行,让每个键值对单独占据一行;- 键值对拆分:通过索引
kv_pair(0)和kv_pair(1)分别提取属性名和属性值,同时把值转为整数类型(如果需要保留字符串格式,直接去掉cast(IntegerType)即可); pivot操作:将attribute列的不同取值(year/price/mpg)转换为列名,聚合函数确保每个车辆的每个属性只保留唯一值;- 自动补全null:透视后不存在的属性列会自动填充
null,完全符合你期望的目标DataFrame格式。
最终输出结果
运行代码后会得到如下结果:
+--------+----+-----+----+ |Car name|year|price| mpg| +--------+----+-----+----+ | Toyota|2000|20000|null| | Audi|null| null| 22| +--------+----+-----+----+
内容的提问来源于stack exchange,提问作者sam8686
相关产品推荐
相关产品推荐

